[bzoj3343] 教主的魔法
分块大法。。
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 using namespace std; 7 const int maxn=1002333,knum=1023; 8 int sz[knum],l[knum],r[knum],add[knum]; 9 int bel[maxn],mp[maxn]; 10 int a[knum][1023]; 11 int i,j,k,n,m,kuai; 12 13 int ra;char rx; 14 inline int read(){ 15 rx=getchar(),ra=0; 16 while(rx<'0'||rx>'9')rx=getchar(); 17 while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra; 18 } 19 inline int get(int id,int v){ 20 if(v<=0)return sz[id]; 21 if(v>a[id][sz[id]])return 0; 22 int l=0,r=sz[id]+1,mid; 23 while(l<r) 24 if(a[id][(mid=l+r>>1)]>=v)r=mid;else l=mid+1; 25 return sz[id]-l+1; 26 } 27 inline void insert(int L,int R,int v){ 28 register int i; 29 if(bel[L]==bel[R]){ 30 int id=bel[L]; 31 for(i=L;i<=R;i++)mp[i]+=v; 32 memcpy(a[id]+1,mp+1+l[id],sz[id]<<2); 33 sort(a[id]+1,a[id]+1+sz[id]); 34 return; 35 } 36 int idl=bel[L],idr=bel[R]; 37 for(i=L;i<=r[idl];i++)mp[i]+=v; 38 memcpy(a[idl]+1,mp+1+l[idl],sz[idl]<<2), 39 sort(a[idl]+1,a[idl]+1+sz[idl]); 40 41 for(i=l[idr];i<=R;i++)mp[i]+=v; 42 memcpy(a[idr]+1,mp+1+l[idr],sz[idr]<<2), 43 sort(a[idr]+1,a[idr]+1+sz[idr]); 44 45 for(i=idl+1;i<idr;i++)add[i]+=v; 46 } 47 inline int query(int L,int R,int v){ 48 register int i;int ans=0,idl=bel[L],idr=bel[R]; 49 if(idl==idr){ 50 for(i=L;i<=R;i++)ans+=mp[i]+add[idl]>=v; 51 return ans; 52 } 53 for(i=L;i<=r[idl];i++)ans+=mp[i]+add[idl]>=v; 54 for(i=l[idr];i<=R;i++)ans+=mp[i]+add[idr]>=v; 55 for(i=idl+1;i<idr;i++)ans+=get(i,v-add[i]); 56 return ans; 57 } 58 int main(){ 59 n=read(),m=read(),kuai=min((int)sqrt(n)+5,n);// kuai=50; 60 for(i=1;i<=n;i++)bel[i]=(i+kuai-1)/kuai; 61 for(i=1;i<=bel[n];i++){ 62 l[i]=(i-1)*kuai+1,r[i]=i==bel[n]?n:(l[i]+kuai-1),sz[i]=r[i]-l[i]+1; 63 for(j=l[i];j<=r[i];j++)mp[j]=a[i][j-l[i]+1]=read(); 64 sort(a[i]+1,a[i]+1+sz[i]); 65 // printf("kuai:%d\n",i); 66 // for(j=l[i];j<=r[i];j++)printf("%d ",a[i][j-l[i]+1]);puts(""); 67 // for(j=l[i];j<=r[i];j++)printf("%d ",mp[j]);puts(""); 68 }char s[2];int a,b,c; 69 while(m--){ 70 scanf("%s",s);a=read(),b=read(),c=read(); 71 if(s[0]=='A')printf("%d\n",query(a,b,c));else insert(a,b,c); 72 // for(i=1;i<=n;i++)printf(" %d",mp[i]+add[bel[i]]);puts(""); 73 } 74 return 0; 75 }