[UVA12003] Array Transformer(分块,二分,暴力)

题目链接:https://vjudge.net/problem/UVA-12003

题意:n个数,每次查询[l,r]区间内比v小的数的个数,并且要更新一个位置为另一个值,强制在线。

首先分块,分块后对每一个块排序,查询遇到块的时候二分找比这个值小的,两端则枚举。

更新的时候,修改一个值,冒泡就行了。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3
 4 typedef long long LL;
 5 const int maxn = 300100;
 6 int n, q, sz, be[maxn];
 7 LL u, a[maxn];
 8 vector<LL> block[maxn];
 9
10 LL query(int l, int r, LL v) {
11     LL ret = 0;
12     for(int i = l; i <= r; ) {
13         if(i % sz == 0 && i + sz <= r) {
14             ret += lower_bound(block[be[i]].begin(), block[be[i]].end(), v) - block[be[i]].begin();
15             i += sz;
16         }
17         else {
18             if(a[i] < v) ret++;
19             i++;
20         }
21     }
22     return ret;
23 }
24
25 void update(int p, LL v) {
26     int pre = a[p];
27     a[p] = v;
28     vector<LL>& b = block[be[p]];
29     int pos = 0;
30     while(b[pos] < pre) pos++;
31     b[pos] = v;
32     if(v > pre) {
33         while(pos < b.size() - 1 && b[pos] > b[pos+1]) {
34             swap(b[pos+1], b[pos]);
35             pos++;
36         }
37     }
38     else {
39         while(pos > 0 && b[pos] < b[pos-1]) {
40             swap(b[pos-1], b[pos]);
41             pos--;
42         }
43     }
44 }
45
46 int main() {
47     // freopen("in", "r", stdin);
48     int l, r, p;
49     LL v;
50     while(~scanf("%d%d%d",&n,&q,&u)) {
51         sz = sqrt((double)n);
52         for(int i = 0; i < n; i++) block[i].clear();
53         for(int i = 0; i < n; i++) {
54             scanf("%d", &a[i]);
55             be[i] = i / sz;
56             block[be[i]].push_back(a[i]);
57         }
58         for(int i = 0; i <= sz; i++) {
59             sort(block[i].begin(), block[i].end());
60         }
61         while(q--) {
62             scanf("%d%d%lld%d",&l,&r,&v,&p);
63             l--; r--; p--;
64             LL k = query(l, r, v);
65             update(p, k*u/(r-l+1));
66         }
67         for(int i = 0; i < n; i++) {
68             printf("%lld\n", a[i]);
69         }
70     }
71     return 0;
72 }
时间: 2024-11-02 20:53:22

[UVA12003] Array Transformer(分块,二分,暴力)的相关文章

【bzoj2453】维护队列/【bzoj2120】数颜色 分块+二分

题目描述 你小时候玩过弹珠吗? 小朋友A有一些弹珠,A喜欢把它们排成队列,从左到右编号为1到N.为了整个队列鲜艳美观,小朋友想知道某一段连续弹珠中,不同颜色的弹珠有多少.当然,A有时候会依据个人喜好,替换队列中某个弹珠的颜色.但是A还没有学过编程,且觉得头脑风暴太浪费脑力了,所以向你来寻求帮助. 输入 输入文件第一行包含两个整数N和M. 第二行N个整数,表示初始队列中弹珠的颜色. 接下来M行,每行的形式为"Q L R"或"R x c","Q L R&quo

UVA 12003 Array Transformer

Array Transformer Time Limit: 5000ms Memory Limit: 131072KB This problem will be judged on UVA. Original ID: 1200364-bit integer IO format: %lld      Java class name: Main Write a program to transform an array A[1], A[2],..., A[n] according to m inst

Codeforces 778A:String Game(二分暴力)

http://codeforces.com/problemset/problem/778/A 题意:给出字符串s和字符串p,还有n个位置,每一个位置代表删除s串中的第i个字符,问最多可以删除多少个字符使得s串依旧包含p串. 思路:想到二分,以为二分做法依旧很暴力.但是别人的做法确实就是二分暴力搞啊. 枚举删除字符数,然后判断的时候如果s串包含p串,那么可以往右区间找,否则左区间找. 1 #include <bits/stdc++.h> 2 using namespace std; 3 #def

uva 12003 Array Transformer (块状数组)

大白书上的393页. 一直在原数组上乱搞.其实要用另外一个数组记录块. 原数组是不能变的. 注意好原数组和块数组的关系,细心一点处理边界.还是不难的. #include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #define maxn 300005 #define SIZE 600 using namespace std; int a[maxn]; int bl

【BZOJ1257】余数之和(数论分块,暴力)

[BZOJ1257]余数之和(数论分块,暴力) 题解 Description 给出正整数n和k,计算j(n, k)=k mod 1 + k mod 2 + k mod 3 + - + k mod n的值,其中k mod i表示k除以i的余数.例如j(5, 3)=3 mod 1 + 3 mod 2 + 3 mod 3 + 3 mod 4 + 3 mod 5=0+1+0+3+3=7 Input 输入仅一行,包含两个整数n, k. Output 输出仅一行,即j(n, k). Sample Input

Codeforces#86D Powerful array(分块暴力)

Description An array of positive integers a1,?a2,?...,?an is given. Let us consider its arbitrary subarray al,?al?+?1...,?ar, where 1?≤?l?≤?r?≤?n. For every positive integer s denote by Ks the number of occurrences of s into the subarray. We call the

【bzoj2453】维护队列 (分块 + 二分)

传送门(权限题) 题目分析 题意为:求区间内有多少种不同的数,带修改. 首先对原序列分块,用last[i]表示与i相同的上一个在哪里,然后将分块后的数组每个块内的按照last进行排序,这样查询时就可以暴力枚举散块,看last[i]是否<l,是则ans++,并二分枚举每个整块,查找出last < l 的数的个数即新出现的数.对于修改,修改后暴力重新构建被影响点所在的块. code 3452 ms #include<iostream> #include<cstdio> #i

教主的魔法[分块+二分]

题目描述 教主最近学会了一种神奇的魔法,能够使人长高.于是他准备演示给XMYZ信息组每个英雄看.于是N个英雄们又一次聚集在了一起,这次他们排成了一列,被编号为1.2.…….N. 每个人的身高一开始都是不超过1000的正整数.教主的魔法每次可以把闭区间[L, R](1≤L≤R≤N)内的英雄的身高全部加上一个整数W.(虽然L=R时并不符合区间的书写规范,但我们可以认为是单独增加第L(R)个英雄的身高) CYZ.光哥和ZJQ等人不信教主的邪,于是他们有时候会问WD闭区间 [L, R] 内有多少英雄身高

CF701F String set queries (分块思想+暴力)

很容易想到AC自动机,但是却发现不怎么支持删除 完蛋,怎么办? 思考如何优化暴力 有两种暴力:一种是kmp,一种是trie trie时间复杂度优秀,但空间不行: kmp时间不行 那么我们可以互补一下 对于长度小于 \(sqrt\) 的,我们加入 \(trie\) 中,否则暴力 \(kmp\),这样能够维持时间复杂度,因为总长不大 分块思想真妙! #include <map> #include <set> #include <ctime> #include <que