[luogu1438]无聊的数列

考虑令$b_{i}=a_{i+1}-a_{i}$,那么1操作相当于对L加上K,对(L,R]区间加上D,对R+1减去K+(R-L)*D,然后询问区间和即可

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define L (k<<1)
 4 #define R (L+1)
 5 #define mid (l+r>>1)
 6 int n,m,p,x,y,k,d,a[100005],f[400005],laz[400005];
 7 void up(int k,int l,int r,int x){
 8     laz[k]+=x;
 9     f[k]+=(r-l+1)*x;
10 }
11 void down(int k,int l,int r){
12     up(L,l,mid,laz[k]);
13     up(R,mid+1,r,laz[k]);
14     laz[k]=0;
15 }
16 void update(int k,int l,int r,int x,int y,int z){
17     if ((l>y)||(x>r))return;
18     if ((x<=l)&&(r<=y)){
19         up(k,l,r,z);
20         return;
21     }
22     update(L,l,mid,x,y,z);
23     update(R,mid+1,r,x,y,z);
24     f[k]=f[L]+f[R]+laz[k]*(r-l+1);
25 }
26 int query(int k,int l,int r,int x,int y){
27     if ((l>y)||(x>r))return 0;
28     if ((x<=l)&&(r<=y))return f[k];
29     down(k,l,r);
30     return query(L,l,mid,x,y)+query(R,mid+1,r,x,y);
31 }
32 int main(){
33     scanf("%d%d",&n,&m);
34     for(int i=1;i<=n;i++)scanf("%d",&a[i]);
35     for(int i=1;i<=m;i++){
36         scanf("%d%d",&p,&x);
37         if (p==2)printf("%d\n",a[x]+query(1,1,n,1,x));
38         else{
39             scanf("%d%d%d",&y,&k,&d);
40             update(1,1,n,x,x,k);
41             if (x<y)update(1,1,n,x+1,y,d);
42             if (y<n)update(1,1,n,y+1,y+1,-k-(y-x)*d);
43         }
44     }
45 }
View Code

 

posted @ 2019-08-07 19:55  PYWBKTDA  阅读(105)  评论(0编辑  收藏  举报