教主的魔法--分块
https://www.luogu.org/problemnew/show/P2801
第一次写分块的题,学习了这个视频:
https://www.bilibili.com/video/av6445624?from=search&seid=16889343910066931739
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 void build() 2 { 3 block=sqrt(n); 4 num=n/block; 5 if(n%block) num++; 6 for(int i=1;i<=num;i++) 7 { 8 l[i]=(i-1)*block+1; 9 r[i]=block*i; 10 } 11 r[num]=n; 12 for(int i=1;i<=n;i++) 13 belong[i]=(i-1)/block+1; 14 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<stdio.h> 2 #include<string.h> 3 #include<math.h> 4 #include<iostream> 5 #include<stdlib.h> 6 #include<algorithm> 7 #include<queue> 8 #include<vector> 9 #include<string> 10 #include<set> 11 #include<cctype> 12 #include<sstream> 13 #define mem(a) memset(a,0,sizeof(a)) 14 #define LL long long 15 const int N=1e9+5; 16 const int M=1e6+10; 17 using namespace std; 18 int n,q,a[M],l[M],r[M],block,belong[M],num,add[M],b[M]; 19 int c; 20 void reset(int n) //内排序 21 { 22 int x=l[belong[n]],y=r[belong[n]]; 23 for(int i=x;i<=y;i++) 24 b[i]=a[i]; 25 sort(b+x,b+y+1); 26 } 27 int fin(int n,int c) 28 { 29 int x=l[n],y=r[n]; 30 int last=y; 31 while(x<=y) 32 { 33 int m=(x+y)>>1; 34 if(b[m]<c) x=m+1; 35 else y=m-1; 36 } 37 return last-x+1; 38 } 39 void build() 40 { 41 block=sqrt(n); 42 num=n/block; 43 if(n%block) num++; 44 for(int i=1;i<=num;i++) 45 { 46 l[i]=(i-1)*block+1; 47 r[i]=block*i; 48 } 49 r[num]=n; 50 for(int i=1;i<=n;i++) 51 belong[i]=(i-1)/block+1,b[i]=a[i]; 52 for(int i=1;i<=num;i++) 53 sort(b+l[i],b+r[i]+1); 54 return;// 55 } 56 void update(int L,int R,int c) 57 { 58 if(belong[L]==belong[R]) 59 { 60 for(int i=L;i<=R;i++) 61 { 62 a[i]+=c; 63 } 64 reset(L);// 65 return; 66 } 67 for(int i=L;i<=r[belong[L]];i++) 68 a[i]+=c; 69 for(int i=l[belong[R]];i<=R;i++) 70 a[i]+=c; 71 reset(L);reset(R); 72 for(int i=belong[L]+1;i<belong[R];i++) 73 { 74 add[i]+=c; 75 } 76 } 77 int ask(int ll,int rr,int c) 78 { 79 int ans=0; 80 if(belong[ll]==belong[rr]) 81 { 82 for(int i=ll;i<=rr;i++) 83 { 84 if(a[i]+add[belong[i]]>=c) ans++; 85 } 86 } 87 else 88 { 89 for(int i=ll;i<=r[belong[ll]];i++) 90 if(a[i]+add[belong[i]]>=c)ans++; 91 for(int i=l[belong[rr]];i<=rr;i++) 92 if(a[i]+add[belong[i]]>=c) ans++; 93 } 94 for(int i=belong[ll]+1;i<belong[rr];i++) 95 { 96 ans+=fin(i,c-add[i]); 97 } 98 return ans; 99 } 100 int main() 101 { 102 int L,R,c; 103 char s[5]; 104 scanf("%d %d",&n,&q); 105 for(int i=1;i<=n;i++) 106 { 107 scanf("%d",&a[i]); 108 } 109 build(); 110 while(q--) 111 { 112 scanf("%s %d%d%d",s,&L,&R,&c); 113 if(s[0]=='M') 114 { 115 update(L,R,c); 116 } 117 else 118 { 119 printf("%d\n",ask(L,R,c)); 120 } 121 } 122 123 return 0; 124 }