Given a sequence, two operations are provided:
1. Add a number to the interval
2. query the number of intervals greater than or equal to C.
N <= 100 W. You don't need to think about the decision tree. q <= 3000, start from the chunk ~
Copy a copy of the original array, and sort each part of the copy.
For each modification, the part of the intermediate block is marked and modified on both sides and then rebuilt.
For each query, part of the middle block is divided into two answers, and the two sides are violent enumeration.
Don't forget to mark
#include<cmath>#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#define M 1001001using namespace std;int n,m,ans,block,a[M],b[M],mark[1010];void Rebuild(int x){memcpy(b+x*block+1,a+x*block+1,sizeof(a[0])*(x*block+block<=n?block:n-x*block) );sort(b+x*block+1,b+min(x*block+block,n)+1);}int main(){int i,j,x,y,z;char p[10];cin>>n>>m;for(i=1;i<=n;i++)scanf("%d",&a[i]),b[i]=a[i];block=static_cast<int>(sqrt(n)+1e-7);for(i=0;i*block+1<=n;i++)sort(b+i*block+1,b+min(i*block+block,n)+1);for(i=1;i<=m;i++){scanf("%s%d%d%d",p,&x,&y,&z);if(p[0]=='M'){if((x-1)/block==(y-1)/block){for(j=x;j<=y;j++)a[j]+=z;Rebuild((x-1)/block);continue;}int b1=(x-2)/block+1;int b2=y/block-1;for(j=b1;j<=b2;j++)mark[j]+=z;for(j=x;j<=b1*block;j++)a[j]+=z;for(j=b2*block+block+1;j<=y;j++)a[j]+=z;Rebuild((x-1)/block);Rebuild((y-1)/block);}else{ans=0;if((x-1)/block==(y-1)/block){for(j=x;j<=y;j++)if(a[j]+mark[(j-1)/block]>=z)++ans;printf("%d\n",ans);continue;}int b1=(x-2)/block+1;int b2=y/block-1;for(j=b1;j<=b2;j++)ans+=(b+min(j*block+block,n)+1)-lower_bound(b+j*block+1,b+min(j*block+block,n)+1,z-mark[j]);for(j=x;j<=b1*block;j++)if(a[j]+mark[(j-1)/block]>=z)++ans;for(j=b2*block+block+1;j<=y;j++)if(a[j]+mark[(j-1)/block]>=z)++ans;printf("%d\n",ans);}}}
Bzoj 3343 magic chunks