LOJ 6278 数列分块入门 2
嗯...
题目链接:https://loj.ac/problem/6278
这道题只要加上一个update函数即可,用一个vector来记录当前的元素,分三种情况:
1.在l的块中:直接暴力枚举
2.在r的块中:直接暴力枚举
3.在整块中:二分答案
AC代码:
1 #include<cstdio> 2 #include<iostream> 3 #include<vector> 4 #include<algorithm> 5 #include<cmath> 6 7 using namespace std; 8 9 const int maxn = 100010; 10 const int N = 505; 11 12 int block, num; 13 int L[N], R[N], add[N]; 14 int a[maxn], belong[maxn]; 15 vector<int> vc[N]; 16 17 inline void build(int n){ 18 block = sqrt(n); 19 num = ceil(n * 1.0 / block); 20 for(int i = 1; i <= n; i++){ 21 belong[i] = (i - 1) / block + 1; 22 vc[belong[i]].push_back(a[i]); 23 } 24 for(int i = 1; i <= num; i++){ 25 L[i] = (i - 1) * block + 1; 26 R[i] = i * block; 27 sort(vc[i].begin(), vc[i].end()); 28 } 29 R[num] = n; 30 } 31 32 inline void update(int pos){ 33 vc[pos].clear(); 34 for(int i = L[pos]; i <= R[pos]; i++) vc[pos].push_back(a[i]); 35 sort(vc[pos].begin(), vc[pos].end()); 36 } 37 38 inline void modify(int l, int r, int c){ 39 for(int i = l; i <= min(r, R[belong[l]]); i++) a[i] += c; 40 update(belong[l]); 41 if(belong[l] != belong[r]){ 42 for(int i = L[belong[r]]; i <= r; i++) a[i] += c; 43 update(belong[r]); 44 } 45 for(int i = belong[l] + 1; i < belong[r]; i++) add[i] += c; 46 } 47 48 inline int query(int l, int r, int c){ 49 int ans = 0; 50 for(int i = l; i <= min(r, R[belong[l]]); i++) 51 if(a[i] + add[belong[i]] < c) ans++; 52 if(belong[l] != belong[r]){ 53 for(int i = L[belong[r]]; i <= r; i++) 54 if(a[i] + add[belong[i]] < c) ans++; 55 } 56 for(int i = belong[l] + 1; i < belong[r]; i++) 57 ans += lower_bound(vc[i].begin(), vc[i].end(), c - add[i]) - vc[i].begin(); 58 return ans; 59 } 60 61 int main(){ 62 int n; 63 scanf("%d", &n); 64 for(int i = 1; i <= n; i++) scanf("%d", &a[i]); 65 build(n); 66 for(int i = 1; i <= n; i++){ 67 int opt, l, r, c; 68 scanf("%d%d%d%d", &opt, &l, &r, &c); 69 if(opt == 0) modify(l, r, c); 70 else printf("%d\n", query(l, r, c * c)); 71 } 72 return 0; 73 }