题意:中文题。。。
以前用线段树写过。。现在学Splay,也来写一下。。
用伸展树来进行单点更新和区间查询,单点更新就直接查选第k个直接查选到这个点然后再维护上去就可以了,,区间查选,因为这里是闭区间,所以要先把区间扩大一下(自己用手写下就知道),然后第k个找到左边界的点,旋转到根,找到右边界的点旋转到根的右子树,然后右边界的点的左子树就是要找的答案了。。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN=222222;
struct Node
{
Node *ch[2];
Node *pre;
int size,val,mx;
}p[MAXN];
int num[MAXN];
int tot;
Node *null=&p[0];
Node *root;
Node *new_Node(int val)
{
Node *rt=&p[++tot];
rt->val=val;
rt->size=1;
rt->ch[0]=null;
rt->ch[1]=null;
rt->pre=null;
return rt;
}
void pushup(Node *rt)
{
rt->mx=max(rt->val,max(rt->ch[0]->mx,rt->ch[1]->mx));
rt->size=rt->ch[0]->size+rt->ch[1]->size+1;
}
Node *build(int l,int r)
{
if(l>r)
return null;
Node *rt;
int mid=(l+r)>>1;
rt=new_Node(num[mid-1]);
rt->ch[0]=build(l,mid-1);
rt->ch[0]->pre=rt;
rt->ch[1]=build(mid+1,r);
rt->ch[1]->pre=rt;
pushup(rt);
return rt;
}
void Rotate(Node *x,int c)
{
Node *y=x->pre;
y->ch[!c]=x->ch[c];
if(x->ch[c]!=null)
{
x->ch[c]->pre=y;
}
x->pre=y->pre;
if(y->pre!=null)
{
if(y->pre->ch[0]==y)
y->pre->ch[0]=x;
else
y->pre->ch[1]=x;
}
x->ch[c]=y;
y->pre=x;
if(y==root)
x=root;
pushup(y);
pushup(x);
}
void splay(Node *x,Node *f)
{
while(x->pre!=f)
{
if(x->pre->pre==f)
{
if(x->pre->ch[0]==x)
{
Rotate(x,1);
}
else
{
Rotate(x,0);
}
}
else
{
Node *y=x->pre,*z=y->pre;
if(z->ch[0]==y)
{
if(y->ch[0]==x)
{
Rotate(y,1);
Rotate(x,1);
}
else
{
Rotate(x,0);
Rotate(x,1);
}
}
else
{
if(y->ch[1]==x)
{
Rotate(y,0);
Rotate(x,0);
}
else
{
Rotate(x,1);
Rotate(x,0);
}
}
}
}
pushup(x);
}
Node *kth(Node *rt,int k)
{
if(rt->ch[0]->size+1==k)
return rt;
if(k<=rt->ch[0]->size)
return kth(rt->ch[0],k);
else
return kth(rt->ch[1],k-(rt->ch[0]->size)-1);
}
int main()
{
int n,m,i;
Node *L,*R;
while(scanf("%d%d",&n,&m)==2)
{
for(i=1;i<=n;i++)
scanf("%d",&num[i]);
tot=0;
num[0]=0;
num[n+1]=0;
root=build(1,n+2);
char op[2];
int x,y;
while(m--)
{
scanf("%s%d%d",op,&x,&y);
if(op[0]=='Q')
{
y+=2;
L=kth(root,x);
R=kth(root,y);
splay(L,null);
splay(R,L);
printf("%d\n",R->ch[0]->mx);
root=L;
}
else
{
x++;
L=kth(root,x);
splay(L,null);
root=L;
root->val=y;
pushup(root);
}
}
}
return 0;
}