数列分块入门 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 }

 

posted @ 2019-03-03 21:03  Let_Life_Stop  阅读(279)  评论(0编辑  收藏  举报