Problem H
1 10 1 2 3 4 5 6 7 8 9 10 7 Q 1 5 A 1 5 Q 1 5 D 10 11 Q 10 10 D 10 9 Q 10 10
15 5 20 6 10 10 1 1
/*用线段树维护*/ #include<iostream> #include<cstring> #include<cmath> #include<cstdio> #include<ctime> #include<cstdlib> #define N 50005 using namespace std; struct data { int be,en; //覆盖的区域 int left,right; //左右儿子的编号 int max,sum; }tree[4*N]; int a[N],tot; int MAX(int a,int b) { return a>b?a:b; } void make_tree(int st,int en) //建树 { int now=++tot; tree[now].be=st,tree[now].en=en; if(st==en) tree[now].max=tree[now].sum=a[st]; else { int mid=(st+en)/2; tree[now].left=tot+1; make_tree(st,mid); tree[now].right=tot+1; make_tree(mid+1,en); tree[now].max=MAX(tree[tree[now].left].max,tree[tree[now].right].max); tree[now].sum=tree[tree[now].left].sum+tree[tree[now].right].sum; } } void del(int v,int m,int k) //更新点 m 处的值 { if(tree[v].be==tree[v].en && tree[v].en==m) { if(tree[v].sum>=k) { tree[v].sum-=k; tree[v].max-=k; } return; } int mid=(tree[v].be+tree[v].en)/2; if(m<=mid) del(tree[v].left,m,k); else del(tree[v].right,m,k); tree[v].max=MAX(tree[tree[v].left].max,tree[tree[v].right].max); tree[v].sum=tree[tree[v].left].sum+tree[tree[v].right].sum; } int qumax(int v,int st,int en) //取区间[st,en]的最大值 { if(st<=tree[v].be && en>=tree[v].en) return tree[v].max; int mid=(tree[v].be+tree[v].en)/2; if(en<=mid) return qumax(tree[v].left,st,en); if(st>mid) return qumax(tree[v].right,st,en); return MAX(qumax(tree[v].left,st,mid),qumax(tree[v].right,mid+1,en)); } int qusum(int v,int st,int en) //取区间[st,en] 的和 { if(st<=tree[v].be && en>=tree[v].en) return tree[v].sum; int mid=(tree[v].be+tree[v].en)/2; if(en<=mid) return qusum(tree[v].left,st,en); if(st>mid) return qusum(tree[v].right,st,en); return qusum(tree[v].left,st,mid)+qusum(tree[v].right,mid+1,en); } int main() { int t,n,m; scanf("%d",&t); for(int ca=1;ca<=t;ca++) { memset(a,0,sizeof(a)); memset(tree,0,sizeof(tree)); tot=0; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); make_tree(1,n); scanf("%d",&m); char s[10]; gets(s); for(int i=1;i<=m;i++) { char ch; int k,m; scanf("%c%d%d",&ch,&k,&m); gets(s); if(ch=='Q') printf("%d %d\n",qusum(1,k,m),qumax(1,k,m)); else if(ch=='D') del(1,k,m); else if(ch=='A') del(1,k,-m); } } return 0; }