https://www.luogu.org/problemnew/show/P2801
分块
对于每一块进行排序存储在另一个数组中
二分查询
#include<iostream> #include<cstdio> #include<algorithm> #include<cmath> using namespace std; #define gc getchar() const int N = 1e6 + 10; const int M = 1e3 + 10; int A[N], B[N], Pos[N], Add[M]; int n, Q, cnt, block; inline int read(){ int x = 0, f = 1; char c = gc; while(c < ‘0‘ || c > ‘9‘) {if(c == ‘-‘) f = -1; c = gc;} while(c >= ‘0‘ && c <= ‘9‘) x = x * 10 + c - ‘0‘, c = gc; return x * f; } inline void Sort(int x){ int l = (x - 1) * block + 1, r = min(n, x * block); for(int i = l; i <= r; i ++) B[i] = A[i]; sort(B + l, B + r + 1); } inline void Sec_G(int x, int y, int z){ if(Pos[x] == Pos[y]){for(int i = x; i <= y; i ++) A[i] += z; Sort(Pos[x]); return ;} else { for(int i = x; i <= Pos[x] * block; i ++) A[i] += z; for(int i = (Pos[y] - 1) * block + 1; i <= y; i ++) A[i] += z; Sort(Pos[x]); Sort(Pos[y]); } for(int i = Pos[x] + 1; i < Pos[y]; i ++) Add[i] += z; } inline int to_calc(int x, int num){ int l = (x - 1) * block, r = min(x * block, n), last = r, ans; while(l <= r){ int mid = (l + r) >> 1; if(B[mid] < num) ans = mid, l = mid + 1; else r = mid - 1; } return last - ans + 1; } inline int Sec_A(int x, int y, int z){ int answer(0); if(Pos[x] == Pos[y]){for(int i = x; i <= y; i ++) if(A[i] + Add[Pos[x]] >= z) answer ++; return answer;} else { for(int i = x; i <= Pos[x] * block; i ++) if(A[i] + Add[Pos[x]] >= z) answer ++; for(int i = (Pos[y] - 1) * block + 1; i <= y; i ++) if(A[i] + Add[Pos[y]] >= z) answer ++; } for(int i = Pos[x] + 1; i < Pos[y]; i ++) answer += to_calc(i, z - Add[i]); return answer; } int main() { freopen("gg.in", "r", stdin); n = read(); Q = read(); block = sqrt(n); for(int i = 1; i <= n; i ++) A[i] = read(); for(int i = 1; i <= n; i ++) Pos[i] = (i - 1) / block + 1; for(int i = 1; i <= n; i ++) Sort(i); if(n % block) cnt = n / block + 1; else cnt = n / block; while(Q --){ string s; cin >> s; int x = read(), y = read(), z = read(); if(s[0] == ‘A‘) Sec_G(x, y, z); else cout << Sec_A(x, y, z) << endl; } return 0; } /* 5 3 1 2 3 4 5 A 1 5 4 M 3 5 1 A 1 5 4 */