题目描述
n个小怪兽站成一行跳来跳去。每次跳跃操作是以下两种形式之一:
a L b:从左到右第a个小怪兽跳过它左边的b个小怪兽,然后落地。
a D b:从左到右第a个小怪兽跳过它右边的b个小怪兽,然后落地。
小怪兽有身高差异,因此在跳跃时需要注意不要碰到其他小怪兽的头。具体来说,每次跳跃的高度等于越过的所有小怪兽的身高的最大值。
你的任务是计算出每次跳跃的高度。
题目大意
单点删除,单点插入,求区间最大值。
数据范围
n,j<=10000
样例输入
9 3
5 3 8 4 9 3 7 4 2
2 D 3
8 L 2
5 D 2
样例输出
9
7
4
解题思路
Splay维护区间,每个点有一个Max和vl属性,分别为当前区间最大值和当前点的值。
注意重新insert一个点后,这个点要设置Size为1,Max=vl。
代码
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#define Maxn 200005
using namespace std;
inline int Getint(){int x=0,f=1;char ch=getchar();while('0'>ch||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while('0'<=ch&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}
inline char Getch(){char ch=getchar();while(!isalpha(ch))ch=getchar();return ch;}
int a[Maxn];
struct splay{
int f[Maxn],son[Maxn][2],vl[Maxn],Max[Maxn],Size[Maxn],root,cnt;
int GetSize(int x){
return Size[son[x][0]]+Size[son[x][1]]+1;
}
void PushUp(int x){
Max[x]=vl[x];
Max[x]=max(Max[son[x][0]],Max[x]);
Max[x]=max(Max[son[x][1]],Max[x]);
Size[x]=GetSize(x);
}
void Rotate(int x){
int fa=f[x],gr=f[fa],s=son[fa][1]==x,sn=son[x][!s];
son[f[x]=gr][son[gr][1]==fa]=x;
son[f[fa]=x][!s]=fa;
son[f[sn]=fa][s]=sn;
PushUp(fa);
PushUp(x);
}
void Splay(int x,int goal){
if(x==goal)return;
while(f[x]!=goal){
if(f[f[x]]!=goal&&(son[f[f[x]]][1]==f[x])==(son[f[x]][1]==x))Rotate(f[x]);
Rotate(x);
}
if(!goal)root=x;
}
int Select(int x){
if(!x)return 0;
int p=root;
while(Size[son[p][0]]+1!=x){
if(x<=Size[son[p][0]])p=son[p][0];
else x-=Size[son[p][0]]+1,p=son[p][1];
}
PushUp(x);
return p;
}
int Delete(int pos){
int u=Select(pos),v=Select(pos+2);
Splay(u,0);
Splay(v,u);
f[son[v][0]]=0;
int ret=vl[son[v][0]];
son[v][0]=0;
Size[son[v][0]]=0;
PushUp(v);
PushUp(u);
return ret;
}
void Insert(int pos,int val){
int u=Select(pos+1),v=Select(pos+2);
Splay(u,0);
Splay(v,u);
vl[++cnt]=val;
Max[cnt]=val;
son[cnt][0]=son[cnt][1]=0;
Size[cnt]=1;
f[cnt]=v;
son[v][0]=cnt;
PushUp(v);
PushUp(u);
}
int Ask(int L,int r){
int u=Select(L),v=Select(r+2);
Splay(u,0);
Splay(v,u);
return Max[son[v][0]];
}
void Build(int L,int r,int fa){
if(L>r)return;
int mid=(L+r)/2;
if(L==r){
Max[mid]=a[mid-1];
Size[mid]=1;
son[mid][0]=son[mid][1]=0;
}
else Build(L,mid-1,mid),Build(mid+1,r,mid);
f[mid]=fa;
vl[mid]=a[mid-1];
PushUp(mid);
son[fa][mid>=fa]=mid;
}
}Solver;
int main(){
int n=Getint(),q=Getint();
for(int i=1;i<=n;i++)a[i]=Getint();
Solver.Build(1,n+2,0);
Solver.root=n+3>>1;
Solver.cnt=n+2;
while(q--){
int pos=Getint();
char ch=Getch();
int Len=Getint();
if(ch=='L')cout<<Solver.Ask(pos-Len,pos-1)<<"\n";
if(ch=='D')cout<<Solver.Ask(pos+1,pos+Len)<<"\n";
int val=Solver.Delete(pos);
if(ch=='D')Solver.Insert(pos+Len-1,val);
if(ch=='L')Solver.Insert(pos-Len-1,val);
}
return 0;
}