数列分块入门 4(涉及区间加法,区间求和)
题目链接:https://loj.ac/problem/6280
题目大意:中文题目
具体思路:模板题,注意add数组在求和的时候的加的位置,在每一段都需要考虑到。
AC代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 # define ll long long 4 const int maxn = 2e6+100; 5 const int inf = 0x3f3f3f3f; 6 ll l[maxn],r[maxn],belong[maxn]; 7 ll add[maxn],a[maxn],sum[maxn]; 8 int n; 9 void buildblock() 10 { 11 ll tmp=(ll)sqrt(n); 12 ll tot=n/tmp; 13 if(n%tmp) 14 tot++; 15 for(ll i=1; i<=n; i++) 16 { 17 belong[i]=(i-1)/tmp+1ll; 18 } 19 for(ll i=1; i<=tot; i++) 20 { 21 l[i]=(i-1)*tmp+1ll; 22 r[i]=i*tmp; 23 } 24 r[tot]=n; 25 for(int i=1; i<=tot; i++) 26 { 27 for(int j=l[i]; j<=r[i]; j++) 28 { 29 sum[i]+=a[j]; 30 } 31 } 32 } 33 void update(ll st,ll ed,ll val) 34 { 35 if(belong[st]==belong[ed]) 36 { 37 for(ll i=st; i<=ed; i++) 38 a[i]+=val,sum[belong[st]]+=val; 39 return ; 40 } 41 for(ll i=st; i<=r[belong[st]]; i++) 42 a[i]+=val,sum[belong[st]]+=val; 43 for(ll i=l[belong[ed]]; i<=ed; i++) 44 a[i]+=val,sum[belong[ed]]+=val; 45 for(ll i=belong[st]+1; i<belong[ed]; i++) 46 add[i]+=val; 47 } 48 ll ask(ll st,ll ed,ll mod) 49 { 50 ll ans=0; 51 if(belong[st]==belong[ed]) 52 { 53 for(ll i=st; i<=ed; i++) 54 { 55 ans+=a[i]+add[belong[st]]; 56 } 57 return ans; 58 } 59 for(ll i=st; i<=r[belong[st]]; i++) 60 { 61 ans+=a[i]+add[belong[st]]; 62 } 63 for(ll i=l[belong[ed]]; i<=ed; i++) 64 { 65 ans+=a[i]+add[belong[ed]]; 66 } 67 for(ll i=belong[st]+1; i<belong[ed]; i++) 68 { 69 ans+=add[i]*(r[i]-l[i]+1)+sum[i]; 70 } 71 return ans; 72 } 73 int main() 74 { 75 scanf("%d",&n); 76 for(int i=1; i<=n; i++) 77 { 78 scanf("%lld",&a[i]); 79 } 80 buildblock(); 81 ll op,st,ed; 82 ll val; 83 while(n--) 84 { 85 scanf("%lld %lld %lld %lld",&op,&st,&ed,&val); 86 if(op==0) 87 { 88 update(st,ed,val); 89 } 90 else if(op==1) 91 { 92 val++; 93 ll tmp=ask(st,ed,val); 94 while(tmp<0) 95 { 96 tmp+=val; 97 } 98 printf("%lld\n",tmp%val); 99 } 100 } 101 return 0; 102 103 }