传送门
这道题序列很长,但是操作数很少,然后也没想到什么好的数据结构来维护,那就分块吧。
感觉维护的过程很好想,修改的时候对于整个块都在内的直接打标记,两个零散的区间暴力重构,重新排序。查询的时候,对于整块的,直接在块内lowerbound一下z-add[i]的位置,零散的话直接暴力计算即可。
复杂度O(ksqrt(n)logsqrt(n)).注意数组别开小了……
#include<cstdio> #include<algorithm> #include<cstring> #include<iostream> #include<cmath> #include<set> #include<queue> #define rep(i,a,n) for(int i = a;i <= n;i++) #define per(i,n,a) for(int i = n;i >= a;i--) #define enter putchar('\n')using namespace std; typedef long long ll; const int M = 2000005; const int N = 2005; const ll INF = 1e17+9; const ll mod = 19260817;ll read() {ll ans = 0,op = 1;char ch = getchar();while(ch < '0' || ch > '9'){if(ch == '-') op = -1;ch = getchar();}while(ch >= '0' && ch <= '9'){ans *= 10;ans += ch - '0';ans %= mod;ch = getchar();}return ans * op; }ll a[M],b[N][N],l[N],r[N],blo[M],add[N],n,m,B,cnt,g = 1,x,y,z; char s[5];ll query(ll x,ll y,ll z) {ll L = blo[x],R = blo[y],ans = 0;if(L == R){rep(i,x,y) if(a[i] + add[L] >= z) ans++;return ans;}rep(i,L+1,R-1){//rep(j,1,B) printf("%lld ",b[i][j]);enter;//printf("!%lld\n",z - add[i]);int d = lower_bound(b[i]+1,b[i]+B,z - add[i]) - b[i];//printf("#%d\n",d);if(d == B && b[i][d] < z - add[i]) continue;ans += B - d + 1;}rep(i,x,r[L]) if(a[i] + add[blo[i]] >= z) ans++;rep(i,l[R],y) if(a[i] + add[blo[i]] >= z) ans++;return ans; }void modify(ll x,ll y,ll z) {ll L = blo[x],R = blo[y],cur = 0;if(L == R){rep(i,x,y) a[i] += z;rep(i,l[L],r[L]) b[L][++cur] = a[i];sort(b[L]+1,b[L]+1+B);return;}rep(i,L+1,R-1) add[i] += z;rep(i,x,r[L]) a[i] += z;rep(i,l[R],y) a[i] += z;rep(i,l[L],r[L]) b[L][++cur] = a[i];sort(b[L]+1,b[L]+B+1),cur = 0;rep(i,l[R],r[R]) b[R][++cur] = a[i];sort(b[R]+1,b[R]+B+1); }int main() {n = read(),m = read(),B = sqrt(n);cnt = (n % B) ? n / B + 1 : n / B;rep(i,1,cnt) l[i] = r[i-1] + 1,r[i] = l[i] + B - 1;r[cnt] = n;rep(i,1,n) a[i] = read();rep(i,1,n){blo[i] = g;if(i == r[g]) g++;}rep(i,1,cnt){int cur = 0;rep(j,l[i],r[i]) b[i][++cur] = a[j];sort(b[i]+1,b[i]+B+1);}rep(i,1,m){scanf("%s",s);x = read(),y = read(),z = read();if(s[0] == 'A') printf("%lld\n",query(x,y,z));else modify(x,y,z);}return 0; }