[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 }