题目描述:
雾
题目分析:
Splay序列操作裸题,建树的时候最好仿照线段树的建树方法.
题目链接:
Ac 代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define il inline
#define ls ch[x][0]
#define rs ch[x][1]
const int maxm=3000010;
int fa[maxm],ch[maxm][2],siz[maxm];
int root,sz;
int n;
char w[maxm],s[maxm]={0};
il void pushup(int x)
{
siz[x]=siz[ls]+siz[rs]+1;
}
il bool get(int x)
{
return (ch[fa[x]][1]==x);
}
il void rotate(int x)
{
int fax=fa[x],ffa=fa[fax],which=get(x);
bool fx=get(fax);
ch[fax][which]=ch[x][which^1];
fa[ch[fax][which]]=fax;
ch[x][which^1]=fax;
fa[fax]=x;
fa[x]=ffa;
if(ffa)
ch[ffa][fx]=x;
pushup(fax),pushup(x);
}
il void splay(int x,int top)
{
for(int fax;(fax=fa[x])!=top;rotate(x))
if(fa[fax]!=top)
rotate(get(fax)==get(x)?fax:x);
if(!top) root=x;
}
inline int find_rank(int rank)
{
int now=root;
while(1)
{
if(rank<=siz[ch[now][0]]) now=ch[now][0];
else if(siz[ch[now][0]]+1==rank)
{
splay(now,0);
return now;
}
else rank-=siz[ch[now][0]]+1,now=ch[now][1];
}
}
int buildsplay(int l,int r,int fax)
{
if(l>r) return 0;
int mid=(l+r)>>1;
int cur=++sz;
fa[cur]=fax;
w[cur]=s[mid];
ch[cur][0]=buildsplay(l,mid-1,cur);
ch[cur][1]=buildsplay(mid+1,r,cur);
pushup(cur);
return cur;
}
inline void insert(int l,int len)
{
int r1=find_rank(l);
int r2=find_rank(l+1);
splay(r1,0),splay(r2,r1);
ch[r2][0]=buildsplay(1,len,r2);
pushup(r1),pushup(r2);
}
inline void del(int l,int r)
{
int r1=find_rank(l),r2=find_rank(r+2);
splay(r1,0),splay(r2,r1);
ch[r2][0]=0;
pushup(r2),pushup(r1);
}
void dfs(int now)
{
if(ch[now][0]) dfs(ch[now][0]);
printf("%c",w[now]);
if(ch[now][1]) dfs(ch[now][1]);
}
inline void print(int l,int len)
{
int r1=find_rank(l),r2=find_rank(l+len+1);
splay(r1,0),splay(r2,r1);
dfs(ch[r2][0]);
puts("");
}
void init()
{
ch[1][1]=2;
siz[1]=2,siz[2]=1;
fa[2]=1;
root=1,sz=2;
}
int main()
{
//freopen("ha.out","w",stdout);
scanf("%d",&n);
init();
int now=1;
for(int i=1;i<=n;i++)
{
char opt[10];
scanf("%s",opt);
if(opt[0]=='I')
{
int len;
scanf("%d",&len);
for(int j=1;j<=len;j++)
{
char c=getchar();
while(c=='\n'||c=='\r') c=getchar();
s[j]=c;
}
insert(now,len);
}
if(opt[0]=='D')
{
int p;
scanf("%d",&p);
del(now,now+p-1);
}
if(opt[0]=='G')
{
int p;
scanf("%d",&p);
print(now,p);
}
if(opt[0]=='M')
{
int k;
scanf("%d",&k);
now=k+1;
}
if(opt[0]=='P')
now--;
if(opt[0]=='N')
now++;
}
return 0;
}