题目描述:这里
思路:
这题似乎是道分块裸题。在查询时,我们可以对每个块进行排序,然后二分查找≥k的元素,输出答案。
不幸的是,这道题有点卡分块。我们可以改变块的大小和加入优化进行卡常。
代码:
#include <bits/stdc++.h> #pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize("Ofast") using namespace std; template < typename T > void read(T &x) { int f = 1;x = 0;char c = getchar(); for (;!isdigit(c);c = getchar()) if (c == '-') f = -f; for (; isdigit(c);c = getchar()) x = x * 10 + c - '0'; x *= f; } int block, num, l[1005], r[1005], belong[1000005], a[1000005], tag[1005], n, q; void build() { block = sqrt(n / log2(n)); num = n / block; if(n % block) num++; for(int i = 1;i <= num;i++) { l[i] = (i - 1) * block + 1; r[i] = i * block; } r[num] = n; for(int i = 1;i <= n;i++) belong[i] = (i - 1) / block; } void update(int x, int y, int w) { if(belong[x] == belong[y]) { for(int i = x;i <= y;i++) a[i] += w; } else { for(int i = x;i <= r[belong[x]];i++) a[i] += w; for(int i = l[belong[y]];i <= y;i++) a[i] += w; for(int i = belong[x] + 1;i <= belong[y] - 1;i++) tag[i] += w; } } int query(int x, int y, int k) { if(belong[x] == belong[y]) { int sum = 0; for(int i = x;i <= y;i++) if(a[i] + tag[belong[x]] >= k) sum++; return sum; } else { int sum = 0; for(int i = x;i <= r[belong[x]];i++) if(a[i] + tag[belong[x]] >= k) sum++; for(int i = l[belong[y]];i <= y;i++) if(a[i] + tag[belong[y]] >= k) sum++; for(int i = belong[x] + 1;i <= belong[y] - 1;i++) { sort(a + l[i], a + r[i] + 1); int lft = l[i], rgh = r[i]; while(lft <= rgh) { int mid = (lft + rgh) / 2; if(a[mid] + tag[i] >= k) rgh = mid - 1; else lft = mid + 1; } sum += block - lft + 1; } return sum; } } int main() { //freopen(".in", "r", stdin); //freopen(".out", "w", stdout); cin >> n >> q; for(int i = 1;i <= n;i++) read(a[i]); for(int i = 1;i <= q;i++) { char c; cin >> c; if(c == 'M') { int x, y, w; read(x); read(y); read(w); update(x, y, w); } if(c == 'A') { int x, y, k; read(x); read(y); read(k); cout << query(x, y, k) << endl; } } return 0; }