丧心病狂树
1 #include<iostream> 2 #include<cstdio> 3 #include<string> 4 using namespace std; 5 #define MAX 200005 6 7 int N,M,K; 8 int tree[MAX<<2]; 9 10 void init() 11 { 12 cin>>N>>M; 13 } 14 15 void Build() 16 { 17 for(K=1;K<N+2;K<<=1); 18 for(int i=K+1;i<=K+N;i++){ 19 scanf("%d%*c",&tree[i]); 20 } 21 for(int i=K-1;i>=1;i--){ 22 tree[i]=max( tree[i<<1] , tree[i<<1|1] ); 23 tree[i<<1]=tree[i<<1]-tree[i]; 24 tree[i<<1|1]=tree[i<<1|1]-tree[i]; 25 } 26 } 27 28 int querymax(int a,int b) 29 { 30 int L=-0x3f3f3f3f,R=-0x3f3f3f3f; 31 for( a=a+K-1,b=b+K+1 ; a^b^1 ; a>>=1,b>>=1 ){ 32 L+=tree[a];R+=tree[b]; 33 if((a&1)==0)L=max( L , tree[a^1] ); 34 if((b&1)==1)R=max( R , tree[b^1] ); 35 } 36 L+=tree[a];R+=tree[b]; 37 int res=max(L,R); 38 while(a)res+=tree[a>>=1]; 39 return res; 40 } 41 42 int sum(int a) 43 { 44 int res=0; 45 a+=K; 46 while(a)res+=tree[a],a>>=1; 47 return res; 48 } 49 50 void change(int a,int v) 51 { 52 int A,s,t; 53 a+=K; 54 tree[a]+=v; 55 while(a>1){ 56 A=max(tree[a],tree[a^1]); 57 tree[a]=tree[a]-A; 58 tree[a^1]=tree[a^1]-A; 59 tree[a>>1]=tree[a>>1]+A; 60 a>>=1; 61 } 62 } 63 64 void work() 65 { 66 int a,b; 67 string c; 68 for(int i=1;i<=M;i++){ 69 cin>>c; 70 scanf("%d%d%*c",&a,&b); 71 if(c=="Q") 72 printf("%d\n",querymax(a,b)); 73 else{ 74 int v=sum(a); 75 if(v<b)change(a,b-v); 76 } 77 } 78 } 79 80 int main() 81 { 82 init(); 83 Build(); 84 work(); 85 //system("pause"); 86 return 0; 87 }
补充:对于代码的区间修改
1 int querymax(int s,int t) 2 { 3 int L=0x3f3f3f3f,R=0x3f3f3f3f; 4 for(s=s+K-1,t=t+K+1;s^t^1;s>>=1,t>>=1){ 5 L+=tree[s],R+=tree[t]; 6 if((s&1)==0)L=max( L , tree[s^1] ); 7 if((t&1)==1)R=max( R , tree[t^1] ); 8 } 9 L+=tree[s],R+=tree[t]; 10 int res=max( L , R ); 11 while(s)res+=tree[s>>=1]; 12 return res; 13 }
https://www.luogu.org/problem/show?pid=1531