爱悠闲 > BZOJ 1507 NOI2003 Editor Splay

BZOJ 1507 NOI2003 Editor Splay

分类: BZOJ  |  标签: BZOJ,BZOJ1507,NOI2003,Splay  |  作者: popoqqq 相关  |  发布日期 : 2014-10-02  |  热度 : 692°

题目大意:

1.将光标移动到某一位置
2.在光标后插入一段字符串
3.删除光标后的一段字符
4.输出光标后的一段字符
5.光标--
6.光标++

和1269很像的一道题,不过弱多了

几个问题需要注意:

1.插入的字符串中间居然会有回车!!没办法了,只能逐个字符进行读入,一旦读到'\n'或者'\r'就重新读入

2.题目描述中说Delete和Get操作后面一定会有足够的字符 纯属放P 连样例都没有足够的字符用来删除 所以删除时要和字符串长度取一个最小值

然后就水水地过去了~

30%达成 今天是不是可以休息了0.0 妈蛋先把圆上的整点搞过去再说

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
struct abcd{
	abcd *fa,*ls,*rs;
	char c;
	int siz;
	bool rev_mark;
	abcd (char C);
	void Push_Up();
}*null=new abcd(0),*root=null;
abcd :: abcd(char C)
{
	fa=ls=rs=null;
	c=C;
	siz=C?1:0;
	rev_mark=0;
}
void abcd :: Push_Up()
{
	siz=ls->siz+rs->siz+1;
}
void Zig(abcd *x)
{
	abcd *y=x->fa;
	y->ls=x->rs;
	x->rs->fa=y;
	x->rs=y;
	x->fa=y->fa;
	if(y==y->fa->ls)
		y->fa->ls=x;
	else if(y==y->fa->rs)
		y->fa->rs=x;
	y->fa=x;
	y->Push_Up();
	if(y==root)
		root=x;
}
void Zag(abcd *x)
{
	abcd *y=x->fa;
	y->rs=x->ls;
	x->ls->fa=y;
	x->ls=y;
	x->fa=y->fa;
	if(y==y->fa->ls)
		y->fa->ls=x;
	else if(y==y->fa->rs)
		y->fa->rs=x;
	y->fa=x;
	y->Push_Up();
	if(y==root)
		root=x;
}
void Splay(abcd *x,abcd *Tar)
{
	while(1)
	{
		abcd *y=x->fa,*z=y->fa;
		if(y==Tar)
			break ;
		if(z==Tar)
		{
			if(x==y->ls)
				Zig(x);
			else
				Zag(x);
			break;
		}
		if(x==y->ls)
		{
			if(y==z->ls)
				Zig(y);
			Zig(x);
		}
		else
		{
			if(y==z->rs)
				Zag(y);
			Zag(x);
		}
	}
	x->Push_Up();
}
void Find(abcd *x,int y,abcd *z)
{
	while(1)
	{
		if(y<=x->ls->siz)
			x=x->ls;
		else
		{
			y-=x->ls->siz;
			if(y==1)
				break;
			y--;
			x=x->rs;
		}
	}
	Splay(x,z);
}
void Output(abcd *x)
{
	if(x==null)
		return ;
	Output(x->ls);
	putchar(x->c);
	Output(x->rs);
}
char s[1<<21];
void Build_Tree(abcd *&x,int l,int r)
{
	if(l>r)
		return ;
	int mid=l+r>>1;
	x=new abcd(s[mid]);
	Build_Tree(x->ls,l,mid-1);
	Build_Tree(x->rs,mid+1,r);
	if(x->ls!=null)
		x->ls->fa=x;
	if(x->rs!=null)
		x->rs->fa=x;
	x->Push_Up();
}
int cursor,m;
int main()
{
	int i,j,x;
	char p[100];
	cin>>m;
	{
		root=new abcd('\n');
		root->rs=new abcd('\n');
		root->rs->fa=root;
		root->Push_Up();
	}
	for(i=1;i<=m;i++)
	{
		scanf("%s",p);
		if(p[0]=='M')
			scanf("%d",&cursor);
		else if(p[0]=='I')
		{
			scanf("%d",&x);
			for(j=0;j<x;j++)
			{
				do s[j]=getchar(); while(s[j]<32);
			}
			Find(root,cursor+1,null);
			Find(root,cursor+2,root);
			Build_Tree(root->rs->ls,0,x-1);
			root->rs->ls->fa=root->rs;
			root->rs->Push_Up();
			root->Push_Up();
		}
		else if(p[0]=='D')
		{
			scanf("%d",&x);
			Find(root,cursor+1,null);
			Find(root,min(cursor+x+2,root->siz),root);
			root->rs->ls=null;
			root->rs->Push_Up();
			root->Push_Up();
		}
		else if(p[0]=='G')
		{
			scanf("%d",&x);
			Find(root,cursor+1,null);
			Find(root,min(cursor+x+2,root->siz),root);
			Output(root->rs->ls);
			puts("");
		}
		else if(p[0]=='P')
			cursor--;
		else
			cursor++;
	}
}