题目大意:
给你一个长度为$n(nleq 50000)$的序列$A$,支持进行以下两种操作:
1.将区间$[l,r]$中所有数加上$c$;
2.询问$A_r$的值。
思路:
分块。
对于整块的数据打标记,零散的数据直接修改。
1 #include<cmath> 2 #include<cstdio> 3 #include<cctype> 4 inline int getint() { 5 register char ch; 6 register bool neg=false; 7 while(!isdigit(ch=getchar())) if(ch=='-') neg=true; 8 register int x=ch^'0'; 9 while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0'); 10 return neg?-x:x; 11 } 12 const int N=50001; 13 int val[N],tag[N],bel[N]; 14 int main() { 15 const int n=getint(),block=sqrt(n); 16 for(register int i=1;i<=n;i++) { 17 val[i]=getint(); 18 bel[i]=i/block; 19 } 20 for(register int i=0;i<n;i++) { 21 const int opt=getint(),l=getint(),r=getint(),c=getint(); 22 if(opt) { 23 printf("%d ",val[r]+tag[bel[r]]); 24 } else { 25 if(bel[l]==bel[r]) { 26 for(register int i=l;i<=r;i++) val[i]+=c; 27 } else { 28 for(register int i=l;bel[i]==bel[l];i++) val[i]+=c; 29 for(register int i=r;bel[i]==bel[r];i--) val[i]+=c; 30 for(register int i=bel[l]+1;i<bel[r];i++) tag[i]+=c; 31 } 32 } 33 } 34 return 0; 35 }