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
#include
#include
#include
#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;
}