BZOJ 1269 文本编辑器 Splay

题目大意:维护一个文本编辑器,支持下列操作:

1.将光标移动到某一位置

2.在光标后插入一段字符串

3.删除光标后的一段字符

4.翻转光标后的一段字符

5.输出光标后的一个字符

6.光标--

7.光标++

Splay中比较水的一道题,标记只有区间翻转,也不用维护区间总值,唯独需要注意的就是插入的时候fa要记得赋值,不然就会像本蒟蒻一样调半天,,,

这题要注意的是Insert操作的读入 首先读入第一个不是‘\n‘或者‘\r‘的字符,然后如果长度不为1就继续gets() 记住是get()不是scanf

然后就没啥了。。。 20%达成 啊啊爽翻天

#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 Reverse();
	void Push_Up();
	void Push_Down();
}*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 :: Reverse()
{
	rev_mark^=1;
	swap(ls,rs);
}
void abcd :: Push_Up()
{
	siz=ls->siz+rs->siz+1;
}
void abcd :: Push_Down()
{
	if(rev_mark)
	{
		ls->Reverse();
		rs->Reverse();
		rev_mark=0;
	}
}
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)
	{
		x->Push_Down();
		if(y<=x->ls->siz)
			x=x->ls;
		else
		{
			y-=x->ls->siz;
			if(y==1)
				break;
			y--;
			x=x->rs;
		}
	}
	Splay(x,z);
}
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,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);
			do s[0]=getchar(); while(s[0]=='\n'||s[0]=='\r');
			if(x^1) gets(s+1);
			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,cursor+x+2,root);
			root->rs->ls=null;
			root->rs->Push_Up();
			root->Push_Up();
		}
		else if(p[0]=='R')
		{
			scanf("%d",&x);
			Find(root,cursor+1,null);
			Find(root,cursor+x+2,root);
			root->rs->ls->Reverse();
		}
		else if(p[0]=='G')
		{
			Find(root,cursor+2,null);
			printf("%c\n",root->c);
		}
		else if(p[0]=='P')
			cursor--;
		else
			cursor++;
	}
}
时间: 2024-08-24 19:13:40

BZOJ 1269 文本编辑器 Splay的相关文章

HYSBZ - 1269 文本编辑器editor (Splay 字符串的区间操作)

文本编辑器editor Time Limit: 10000MS   Memory Limit: 165888KB   64bit IO Format: %lld & %llu Description 这些日子,可可不和卡卡一起玩了,原来可可正废寝忘食的想做一个简单而高效的文本编辑器.你能帮助他吗?为了明确任务目标,可可对“文本编辑器”做了一个抽象的定义:   文本:由0个或多个字符构成的序列.这些字符的ASCII码在闭区间[32, 126]内,也就是说,这些字符均为可见字符或空格.光标:在一段文

BZOJ 1269: [AHOI2006]文本编辑器editor( splay )

splay..( BZOJ 1507 题目基本相同..双倍经验 ) ----------------------------------------------------------------------------- #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #define rep( i , n ) for( int i = 0 ; i <

【BZOJ】【1269】【AHOI2006】文本编辑器editor

Splay Splay序列维护的模板题了……为了便于处理边界情况,我们可以先插入两个空格当作最左端和最右端,然后……其实本题主要考察的就是Build.splay和Findkth这三个操作,我们可以实现一个splay(x,s)操作,使x结点旋转到s结点的下方(如果s为0则x旋转到根),这样可以方便地提取出要处理的区间. 这份模板我还是比较满意的,因为写的没那么长…… 1 /**************************************************************

BZOJ 1269 【AHOI2006】 文本编辑器editor

题目链接:文本编辑器editor 这道题没啥好说的,直接上\(Splay\)就行了,板子题-- 但是我某个地方忘了下放标记导致调了一晚上 保存一发板子: #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #define File(s) freopen(s".in","r",std

1269: [AHOI2006]文本编辑器editor

1269: [AHOI2006]文本编辑器editor Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 4718  Solved: 1807[Submit][Status][Discuss] Description 这些日子,可可不和卡卡一起玩了,原来可可正废寝忘食的想做一个简单而高效的文本编辑器.你能帮助他吗?为了明确任务目标,可可对“文本编辑器”做了一个抽象的定义:   文本:由0个或多个字符构成的序列.这些字符的ASCII码在闭区间[32,

[bzoj1269][AHOI2006文本编辑器editor] (splay模版题)

Description 这些日子,可可不和卡卡一起玩了,原来可可正废寝忘食的想做一个简单而高效的文本编辑器.你能帮助他吗?为了明确任务目标,可可对“文本编辑器”做了一个抽象的定义:   文本:由0个或多个字符构成的序列.这些字符的ASCII码在闭区间[32, 126]内,也就是说,这些字符均为可见字符或空格.光标:在一段文本中用于指示位置的标记,可以位于文本的第一个字符之前,文本的最后一个字符之后或文本的某两个相邻字符之间.文本编辑器:为一个可以对一段文本和该文本中的一个光标进行如下七条操作的程

【BZOJ1269】[AHOI2006]文本编辑器editor Splay

[BZOJ1269][AHOI2006]文本编辑器editor Description 这些日子,可可不和卡卡一起玩了,原来可可正废寝忘食的想做一个简单而高效的文本编辑器.你能帮助他吗?为了明确任务目标,可可对"文本编辑器"做了一个抽象的定义:   文本:由0个或多个字符构成的序列.这些字符的ASCII码在闭区间[32, 126]内,也就是说,这些字符均为可见字符或空格.光标:在一段文本中用于指示位置的标记,可以位于文本的第一个字符之前,文本的最后一个字符之后或文本的某两个相邻字符之间

[AHOI2006]文本编辑器editor (Splay tree)

我感觉伸展树越来越模版了,没想到这么轻易的就过了... 把光标位置标记为pos MOVE:pos++或者pos-- INSERT:把光标旋转至根部,然后把光标后一个字母旋转至根的右子树,然后把insert的内容插入到root的右子树的左子树 ROTATE:把光标旋转至根部,然后把光标后一个字母旋转至根的右子树,然后把rev[root10]取反 GET:得到光标位置的后继,可以GET_KTH后然后GET_NEXT,也可以直接旋转,或者旋转后GET_MIN PREV,NEXT:都只需要改变光标位置变

洛谷P4008 [NOI2003]文本编辑器【splay】

题目描述 很久很久以前,$DOS3.x$ 的程序员们开始对 $EDLIN$ 感到厌倦.于是,人们开始纷纷改用自己写的文本编辑器?? 多年之后,出于偶然的机会,小明找到了当时的一个编辑软件.进行了一些简单的测试后,小明惊奇地发现:那个软件每秒能够进行上万次编辑操作(当然,你不能手工进行这样的测试) !于是,小明废寝忘食地想做一个同样的东西出来.你能帮助他吗? 为了明确目标,小明对"文本编辑器"做了一个抽象的定义: 文本:由 0 个或多个 ASCII 码在闭区间[3232 , 126126