分块模板

区间修改,区间求值

 1 const int N=100010;
 2 ll a[N],sum[N],add[N];
 3 int L[N],R[N],pos[N];
 4 int n,m,ds;
 5 
 6 void modify(int l,int r,ll k)
 7 {
 8     int p=pos[l],q=pos[r];
 9     if(p==q)
10     {
11         FOR(i,l,r) a[i]+=k;
12         sum[p]+=(r-l+1)*k;
13         return;
14     }
15     FOR(i,p+1,q-1) add[i]+=k;
16     FOR(i,l,R[p]) a[i]+=k;
17     sum[p]+=(R[p]-l+1)*k;
18     FOR(i,L[q],r) a[i]+=k;
19     sum[q]+=(r-L[q]+1)*k;
20 }
21 
22 ll query(int l,int r)
23 {
24     int p=pos[l],q=pos[r];
25     ll ans=0;
26     if(p==q)
27     {
28         FOR(i,l,r) ans+=a[i];
29         ans+=add[p]*(r-l+1);
30         return ans;
31     }
32     FOR(i,p+1,q-1)
33         ans+=sum[i]+add[i]*(R[i]-L[i]+1);
34     FOR(i,l,R[p]) ans+=a[i];
35     ans+=(R[p]-l+1)*add[p];
36     FOR(i,L[q],r) ans+=a[i];
37     ans+=(r-L[q]+1)*add[q];
38     return ans;
39 }
40 
41 int main()
42 {
43     scanf("%d%d",&n,&m);
44     FOR(i,1,n) scanf("%lld",&a[i]);
45     ds=sqrt(n);
46     FOR(i,1,ds)
47         L[i]=(i-1)*ds+1,
48         R[i]=i*ds;
49     if(R[ds]<n) ++ds,L[ds]=R[ds-1]+1,R[ds]=n;
50     FOR(i,1,ds) FOR(j,L[i],R[i]) pos[j]=i,sum[i]+=a[j];
51     int opt,l,r;ll k;
52     while(m--)
53     {
54         scanf("%d%d%d",&opt,&l,&r);
55         if(opt==1)
56         {
57             scanf("%lld",&k);
58             modify(l,r,k);
59         }
60         else printf("%lld\n",query(l,r));
61     }
62     return 0;
63 }

 

posted @ 2019-03-16 21:28  universeplayer  阅读(204)  评论(0编辑  收藏  举报