"盛大游戏杯" M 风力观测 (线段树)
题目链接:"盛大游戏杯" M 风力观测
题意:
给你n个数,现在有m个操作。
1 L R V 给[L,R]区间全部加V.
2 X 询问X这个点 历史的绝对值最大是多少。
题解:
对于每个询问,其实我们只需要记录下在这个过程中最大的偏移量和最小的偏移量就行了。
所以直接一个线段树搞一搞就行了。
1 #include<bits/stdc++.h> 2 #define ls l,m,rt<<1 3 #define rs m+1,r,rt<<1|1 4 #define mst(a,b) memset(a,b,sizeof(a)) 5 #define F(i,a,b) for(int i=a;i<=b;++i) 6 using namespace std; 7 8 const int N=1e5+7; 9 int mx[N*4],mi[N*4],val[N*4]; 10 int n,a[N],t,m; 11 12 void PD(int rt) 13 { 14 if(mx[rt]||mi[rt]) 15 { 16 int tmp=val[rt<<1]+mx[rt]; 17 if(tmp>0)mx[rt<<1]=max(mx[rt<<1],tmp); 18 tmp=val[rt<<1]+mi[rt]; 19 if(tmp<0)mi[rt<<1]=min(mi[rt<<1],val[rt<<1]+mi[rt]); 20 tmp=val[rt<<1|1]+mx[rt]; 21 if(tmp>0)mx[rt<<1|1]=max(mx[rt<<1|1],tmp); 22 tmp=val[rt<<1|1]+mi[rt]; 23 if(tmp<0)mi[rt<<1|1]=min(mi[rt<<1|1],tmp); 24 val[rt<<1]+=val[rt],val[rt<<1|1]+=val[rt]; 25 mx[rt]=mi[rt]=val[rt]=0; 26 } 27 } 28 29 void update(int L,int R,int v,int l=1,int r=n,int rt=1) 30 { 31 if(L<=l&&r<=R) 32 { 33 val[rt]+=v; 34 if(val[rt]>0)mx[rt]=max(mx[rt],val[rt]); 35 else mi[rt]=min(mi[rt],val[rt]); 36 return; 37 } 38 PD(rt); 39 int m=l+r>>1; 40 if(L<=m)update(L,R,v,ls); 41 if(R>m)update(L,R,v,rs); 42 } 43 44 void query(int &mmx,int &mmi,int x,int l=1,int r=n,int rt=1) 45 { 46 if(l==r){mmx=mx[rt],mmi=mi[rt];return;} 47 PD(rt); 48 int m=l+r>>1; 49 if(x<=m)query(mmx,mmi,x,ls); 50 else query(mmx,mmi,x,rs); 51 } 52 53 int main(){ 54 scanf("%d",&t); 55 while(t--) 56 { 57 scanf("%d%d",&n,&m); 58 mst(mx,0),mst(mi,0),mst(val,0); 59 F(i,1,n)scanf("%d",a+i); 60 F(i,1,m) 61 { 62 int x,l,r,v; 63 scanf("%d",&x); 64 if(x==1) 65 { 66 scanf("%d%d%d",&l,&r,&v); 67 update(l,r,v); 68 } 69 else 70 { 71 scanf("%d",&x); 72 int mmx,mmi; 73 query(mmx,mmi,x); 74 printf("%d\n",max(abs(mmx+a[x]),abs(mmi+a[x]))); 75 } 76 } 77 } 78 return 0; 79 }