procedure2012
It's not worth it to know you're not worth it!

[关键字]:splay

[题目大意]:也不说了……太麻烦了……

//==============================================================================

[分析]:就是NOI2005序列维护的简化版,不用维护太多信息、不用延迟……但是要注意要判断从当前光标往后走n各是否超出了当前文本的范围,特殊判断一下查出范围就当只查到最后一个就行了。听说输出时如果用中序遍历有可能爆栈但是本弱菜不会高级做法,直接递归遍历在tyvj上已经ac。

[代码]:

View Code
#include<iostream> 
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
using namespace std;

const int MAXN=1024*1024*2+3;
const int INF=10000000;

struct node
{
int dat,size;
node *c[2],*f;
}SS[MAXN],*null,*root;
int pos,tot,m,len,SC;
char s1[MAXN],s[MAXN],ch;

node *New(int dat,node *fa)
{
node *e=SS+ ++SC;
e->f=fa;
e->dat=dat;
e->size=1;
e->c[0]=e->c[1]=null;
return e;
}

void Update(node *v)
{
if (v==null) return;
v->size=v->c[0]->size+v->c[1]->size+1;
}

void Prepare()
{
SC=-1;
null=NULL;
null=New(-INF,NULL);
null->size=0;
root=New(-INF,null);
root->c[1]=New(-INF,root);
Update(root);
}

void debug(node *v)
{
if (v==null) return;
debug(v->c[0]);
printf("%c",v->dat);
debug(v->c[1]);
}

void Rotate(node *x,int o)
{
node *y=x->f;
y->c[o]=x->c[!o];
x->c[!o]->f=y;
x->f=y->f;
if (y->f->c[0]==y)
y->f->c[0]=x;
else
y->f->c[1]=x;
x->c[!o]=y;
y->f=x;
if (root==y) root=x;
Update(y);
}

void Splay(node *x,node *fa)
{
while (x->f!=fa)
{
if (x->f->f==fa)
if (x->f->c[0]==x)
Rotate(x,0);
else
Rotate(x,1);
else
if (x->f->f->c[0]==x->f)
if (x->f->c[0]==x)
Rotate(x->f,0),Rotate(x,0);
else
Rotate(x,1),Rotate(x,0);
else
if (x->f->c[1]==x)
Rotate(x->f,1),Rotate(x,1);
else
Rotate(x,0),Rotate(x,1);
}
Update(x);
}

void Select(int k,node *fa)
{
node *t;
int temp;
for (t=root;;)
{
temp=t->c[0]->size;
if (temp+1==k) break;
if (k<=temp) t=t->c[0]; else k-=temp+1,t=t->c[1];
}
Splay(t,fa);
}

void Insert(int pos,int tot,char *a)
{
node *t,*z;
t=z=New(a[0],null);
for (int i=1;i<tot;++i)
z=z->c[1]=New(a[i],z);
Select(pos+1,null);
Select(pos+2,root);
root->c[1]->c[0]=t;
t->f=root->c[1];
Splay(z,null);
}

void DELETE(int pos,int tot)
{
Select(pos+1,null);
if (root->size-2>=pos+tot)
Select(pos+tot+2,root);
else
Select(root->size,root);
root->c[1]->c[0]=null;
Splay(root->c[1],null);
}

void GET(int pos,int tot)
{
Select(pos+1,null);
if (root->size>=pos+tot+2)
Select(pos+2+tot,root);
else
Select(root->size,root);
debug(root->c[1]->c[0]);
printf("\n");
}

int main()
{
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
Prepare();
scanf("%d",&m),scanf("%c",&ch);
pos=0;
for (int i=1;i<=m;++i)
{
scanf("%s",s1);
if (s1[0]=='M') scanf("%d",&pos),scanf("%c",&ch);
if (s1[0]=='P') --pos,scanf("%c",&ch);
if (s1[0]=='N') ++pos,scanf("%c",&ch);
if (s1[0]=='I')
{
scanf("%d",&tot),scanf("%c",&ch);
len=0;
while (len<tot)
{
scanf("%c",&ch);
if (ch!='\n') s[len++]=ch;
}
scanf("%c",&ch);
//printf("%s\n",s);
Insert(pos,tot,s);
//debug(root);
//printf("\n");
}
if (s1[0]=='D')
{
scanf("%d",&tot),scanf("%c",&ch);
DELETE(pos,tot);
//debug(root);
//printf("\n");
}
if (s1[0]=='G')
{
scanf("%d",&tot);
GET(pos,tot);
}
}
return 0;
}



posted on 2012-03-30 23:00  procedure2012  阅读(709)  评论(0编辑  收藏  举报