= =鬼知道這是那年的HNOI題,連bzoj上都沒有,其實就是維護一個平衡樹就好了,然後區間查詢,支持刪點加點。
涉及區間操作注意在兩旁添加結點後原數組的標號改動問題,這道題相對來說調的比較快
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
const int N=200010,inf=0x3f3f3f3f;
int n,m;
int sz,root;
int a[N],ch[N][2],size[N],key[N],mx[N],fa[N];
inline void clear(int x){ch[x][0]=ch[x][1]=size[x]=fa[x]=key[x]=0;}
inline void updata(int x)
{
if (x)
{
size[x]=1;
mx[x]=key[x];
if (ch[x][0])
{
size[x]+=size[ch[x][0]];
mx[x]=max(mx[x],mx[ch[x][0]]);
}
if (ch[x][1])
{
size[x]+=size[ch[x][1]];
mx[x]=max(mx[x],mx[ch[x][1]]);
}
}
}
inline int get(int x){return ch[fa[x]][1]==x;}
inline void rotate(int x)
{
int old=fa[x],oldf=fa[old],which=get(x);
ch[old][which]=ch[x][which^1],fa[ch[old][which]]=old;
ch[x][which^1]=old;fa[old]=x;fa[x]=oldf;
if (oldf)ch[oldf][ch[oldf][1]==old]=x;
updata(old);updata(x);
}
inline void splay(int x,int tar)
{
for (int old;(old=fa[x])!=tar;rotate(x))
if (fa[old]!=tar)rotate(get(x)==get(old)?old:x);
if (!tar)root=x;
}
inline int build(int l,int r,int old)
{
if (l>r)return 0;
int now=++sz;
int mid=(l+r)>>1;
key[now]=a[mid];mx[now]=a[mid],size[now]=1;fa[now]=old;
ch[now][0]=build(l,mid-1,now);
ch[now][1]=build(mid+1,r,now);
updata(now);
return now;
}
inline int find(int x)
{
int now=root;
while(1)
{
if (ch[now][0]&&x<=size[ch[now][0]])
now=ch[now][0];
else
{
int temp=1;
if (ch[now][0])
temp+=size[ch[now][0]];
if (x<=temp)return now;
x-=temp;
now=ch[now][1];
}
}
}
inline int findval(int x)
{
int now=root;
while(1)
{
if (ch[now][0]&&x<=size[ch[now][0]])now=ch[now][0];
else
{
int temp=1;
if (ch[now][0])
temp+=size[ch[now][0]];
if (x<=temp)return key[now];
x-=temp;now=ch[now][1];
}
}
}
inline void query(int l,int r)
//L-1,R+1
{
int aa=find(l);
int bb=find(r+2);
splay(aa,0);
splay(bb,aa);
int ans=mx[ch[ch[root][1]][0]];
printf("%d\n",ans);
updata(ch[root][1]);
updata(root);
}
inline void insert(int x,int val)
{
int aa=find(x);
int bb=find(x+1);
splay(aa,0);
splay(bb,aa);
ch[ch[root][1]][0]=++sz;
fa[sz]=ch[root][1];
ch[sz][0]=ch[sz][1]=0;
key[sz]=val;mx[sz]=val;
size[sz]=1;updata(fa[sz]);
updata(root);
}
inline void del(int x)
{
int aa=find(x);
int bb=find(x+2);
splay(aa,0);
splay(bb,aa);
ch[ch[root][1]][0]=0;
updata(ch[root][1]);
updata(root);
}
int main()
{
int st,cnt;
scanf("%d%d",&n,&m);
a[1]=-inf,a[n+2]=inf;
for (int i=1;i<=n;++i)
scanf("%d",&a[i+1]);
root=build(1,n+2,0);
for (int i=1;i<=m;++i)
{
scanf("%d",&st);
char c=getchar();
while(c!='L'&&c!='D')c=getchar();
scanf("%d",&cnt);
if (c=='L')
{
int L=st-cnt;
int R=st-1;
query(L,R);
int val=findval(st+1);
del(st);
insert(L,val);
}
else
{
int L=st+1;
int R=st+cnt;
query(L,R);
int val=findval(st+1);
del(st);
insert(R,val);
}
}
}