Problem I
1 4 5 -2 1 3 5 update 1 3 3 query 6 change 1 3 query 6 query 10
3 1 -1
/*用线段树维护*/ #include<iostream> #include<cstring> #include<cmath> #include<stdio.h> #define N 100005 using namespace std; struct data { int be,en; int left,right,max_id; __int64 bj,max_num; }tree[4*N]; int a[N],tot; void make_tree(int st,int en) //建树 { int now=++tot; tree[now].be=st; tree[now].en=en; if(st==en) { tree[now].max_num=a[st]; tree[now].max_id=st; return; } else { int mid=(st+en)>>1; tree[now].left=tot+1; make_tree(st,mid); tree[now].right=tot+1; make_tree(mid+1,en); if(tree[tree[now].left].max_num>tree[tree[now].right].max_num) { tree[now].max_num=tree[tree[now].left].max_num; tree[now].max_id=tree[tree[now].left].max_id; } else { tree[now].max_num=tree[tree[now].right].max_num; tree[now].max_id=tree[tree[now].right].max_id; } } } void clear(int v) { tree[tree[v].left].bj+=tree[v].bj;//给左儿子遗传标记 tree[tree[v].right].bj+=tree[v].bj;//给右儿子遗传标记 tree[v].max_num+=tree[v].bj; tree[v].bj=0; } void add(int v,int st,int en,__int64 k) //将原数组中 第 st-->en 的所有元素的值统统加上 k { if(tree[v].be>=st && tree[v].en<=en) { tree[v].bj+=k; return; } if(tree[v].bj!=0) clear(v); int mid=(tree[v].be+tree[v].en)>>1; if(st>mid) add(tree[v].right,st,en,k); else if(en<=mid) add(tree[v].left,st,en,k); else { add(tree[v].right,st,en,k); add(tree[v].left,st,en,k); } if(tree[tree[v].left].bj!=0) clear(tree[v].left); if(tree[tree[v].right].bj!=0) clear(tree[v].right); if(tree[tree[v].left].max_num>tree[tree[v].right].max_num) { tree[v].max_num=tree[tree[v].left].max_num; tree[v].max_id=tree[tree[v].left].max_id; } else { tree[v].max_num=tree[tree[v].right].max_num; tree[v].max_id=tree[tree[v].right].max_id; } } void change(int v,int k,__int64 num)//改变原数组中第k个元素的值为 num { if(tree[v].be==tree[v].en && tree[v].be==k) { tree[v].max_num=num; return; } if(tree[v].bj) clear(v); if(tree[v].be==tree[v].en) return; int mid=(tree[v].be+tree[v].en)>>1; if(k<=mid) change(tree[v].left,k,num); if(k>mid) change(tree[v].right,k,num); if(tree[tree[v].left].bj) clear(tree[v].left); if(tree[tree[v].right].bj) clear(tree[v].right); if(tree[tree[v].left].max_num>tree[tree[v].right].max_num) { tree[v].max_num=tree[tree[v].left].max_num; tree[v].max_id=tree[tree[v].left].max_id; } else { tree[v].max_num=tree[tree[v].right].max_num; tree[v].max_id=tree[tree[v].right].max_id; } } __int64 get(int v,int k) //获得原数组中第k个位置的值 { if(tree[v].bj!=0) clear(v); if(tree[v].be==tree[v].en && tree[v].be==k) return tree[v].max_num; int mid=(tree[v].be+tree[v].en)>>1; if(k>mid) return get(tree[v].right,k); if(k<=mid) return get(tree[v].left,k); } int get_id(int v,__int64 num) //获得不小于 num 的 最大的位置的值 { if(tree[v].bj) clear(v); if(tree[v].be==tree[v].en) { if(tree[v].max_num>=num) return tree[v].max_id; else return -1; } if(tree[tree[v].left].bj) clear(tree[v].left); if(tree[tree[v].right].bj) clear(tree[v].right); if(tree[tree[v].right].max_num>=num) return get_id(tree[v].right,num); else if(tree[tree[v].left].max_num>=num) return get_id(tree[v].left,num); else return -1; } int main() { int t,n,m; scanf("%d",&t); while(t--) { memset(a,0,sizeof(a)); memset(tree,0,sizeof(tree)); scanf("%d%d",&n,&m); tot=0; for(int i=1;i<=n;i++) scanf("%d",&a[i]); make_tree(1,n); char s[10]; getchar(); for(int i=1;i<=m;i++) { char ch; __int64 c; int k,m; scanf("%s%d",s,&k); if(s[0]=='u') { scanf("%d%I64d",&m,&c); add(1,k,m,c); } else if(s[0]=='c') { scanf("%d",&m); __int64 num1=get(1,k),num2=get(1,m); change(1,m,num1); change(1,k,num2); } else { printf("%d\n",get_id(1,k)); } getchar(); } } return 0; }