HYSBZ 1269 文本编辑器editor

Description

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

Input

输入文件中第一行是指令条数N,以下是需要执行的N个操作。除了回车符之外,输入文件的所有字符的ASCII码都在闭区间[32, 126]内。且行尾没有空格。

Output

依次对应输入文件中每条GET指令的输出,不得有任何多余的字符。

Sample Input

10
Insert 13
Balanced eert
Move 2
Delete 5
Next
Insert 7
editor
Move 0
Get
Move 11
Rotate 4
Get

Sample Output

B
t

Hint

对输入数据我们有如下假定: MOVE操作不超过50 000个,INSERT、DELETE和ROTATE操作作的总个数不超过6 000,GET操作不超过20 000个,PREV和NEXT操作的总个数不超过20 000。 所有INSERT插入的字符数之和不超过2M(1M=1 024*1 024)。 DELETE操作、ROTATE操作和GET操作执行时光标后必然有足够的字符。MOVE、PREV、NEXT操作不会把光标移动到非法位置。 输入文件没有错误。


这题操作比较多,但其实都是splay的经典操作,熟练掌握以后条理就很清晰了,写的也很简单。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<vector>
#include<iostream>
#include<algorithm>
#include<bitset>
#include<functional>
using namespace std;
typedef unsigned long long ull;
typedef long long LL;
const int maxn = 3e6;
int T, root, x;
char s[maxn];

struct Splays
{
	const static int maxn = 3e6;			//节点个数
	const static int INF = 0x7FFFFFFF;			//int最大值
	int ch[maxn][2], F[maxn], sz;				//左右儿子,父亲节点和节点总个数
	int C[maxn], R[maxn];
	char S[maxn];
	int Node(int f, char s) { S[sz] = s; C[sz] = 1; R[sz] = ch[sz][0] = ch[sz][1] = 0; F[sz] = f; return sz++; }//申请一个新节点
	void clear(){ sz = 1; ch[0][0] = ch[0][1] = F[0] = 0; C[0] = 0; }//清空操作
	void pushdown(int x)
	{
		if (!R[x]) return;
		R[ch[x][0]] ^= 1;	R[ch[x][1]] ^= 1;
		swap(ch[x][0], ch[x][1]);	R[x] = 0;
	}
	void rotate(int x, int k)
	{
		int y = F[x]; ch[y][!k] = ch[x][k]; F[ch[x][k]] = y;
		if (F[y]) ch[F[y]][y == ch[F[y]][1]] = x;
		F[x] = F[y];    F[y] = x;	ch[x][k] = y;
		C[x] = C[y];	C[y] = C[ch[y][0]] + C[ch[y][1]] + 1;
	}
	void Splay(int x, int r)
	{
		for (int fa = F[r]; F[x] != fa;)
		{
			if (F[F[x]] == fa) { rotate(x, x == ch[F[x]][0]); return; }
			int y = x == ch[F[x]][0], z = F[x] == ch[F[F[x]]][0];
			y^z ? (rotate(x, y), rotate(x, z)) : (rotate(F[x], z), rotate(x, y));
		}
	}
	void build(int fa, int &x, int l, int r, char *s)
	{
		if (l > r) return;
		int mid = l + r >> 1;
		x = Node(fa, s[mid]);
		build(x, ch[x][0], l, mid - 1, s);
		build(x, ch[x][1], mid + 1, r, s);
		C[x] += C[ch[x][0]] + C[ch[x][1]];
	}
	void Move(int &x, int y)
	{
		for (int i = x; i;)
		{
			pushdown(i);
			if (y < C[ch[i][0]]) { i = ch[i][0]; continue; }
			if (y == C[ch[i][0]]) { Splay(i, x); x = i; break; }
			y -= C[ch[i][0]] + 1;	i = ch[i][1];
		}
	}
	void Delete(int &x, int y)
	{
		for (int i = ch[x][1]; i;)
		{
			pushdown(i);
			if (y < C[ch[i][0]]) { i = ch[i][0]; continue; }
			if (y == C[ch[i][0]]) { Splay(i, ch[x][1]); ch[x][1] = i; break; }
			y -= C[ch[i][0]] + 1;	i = ch[i][1];
		}
		int add = C[ch[ch[x][1]][0]];
		ch[ch[x][1]][0] = 0;	C[x] -= add;	C[ch[x][1]] -= add;
	}
	void Rotate(int &x, int y)
	{
		for (int i = ch[x][1]; i;)
		{
			pushdown(i);
			if (y < C[ch[i][0]]) { i = ch[i][0]; continue; }
			if (y == C[ch[i][0]]) { Splay(i, ch[x][1]); ch[x][1] = i; break; }
			y -= C[ch[i][0]] + 1;	i = ch[i][1];
		}
		R[ch[ch[x][1]][0]] ^= 1;
	}
	void Get(int &x)
	{
		for (int i = ch[x][1]; i; i = ch[i][0])
		{
			pushdown(i);
			if (!ch[i][0]) { Splay(i, ch[x][1]); ch[x][1] = i; break; }
		}
		printf("%c\n", S[ch[x][1]]);
	}
	void Prev(int &x)
	{
		for (int i = ch[x][0]; i; i = ch[i][1])
		{
			pushdown(i);
			if (!ch[i][1]) { Splay(i, x); x = i; break; }
		}
	}
	void Next(int &x)
	{
		for (int i = ch[x][1]; i; i = ch[i][0])
		{
			pushdown(i);
			if (!ch[i][0]) { Splay(i, x); x = i; break; }
		}
	}
	void Insert(int &x, int y)
	{
		gets(s);	gets(s);
		int root = 0;
		build(0, root, 0, y - 1, s);
		for (int i = ch[x][1]; i; i = ch[i][0])
		{
			pushdown(i);
			if (!ch[i][0]) { Splay(i, ch[x][1]); ch[x][1] = i; break; }
		}
		ch[ch[x][1]][0] = root;	F[root] = ch[x][1];
		C[x] += C[root];	C[ch[x][1]] += C[root];
	}
}solve;


int main()
{
	cin >> T;
	root = 0;	solve.clear();
	s[0] = s[1] = 0;
	solve.build(0, root, 0, 1, s);
	while (T--)
	{
		scanf("%s", s);
		if (s[0] == 'M') scanf("%d", &x), solve.Move(root, x);
		if (s[0] == 'D') scanf("%d", &x), solve.Delete(root, x);
		if (s[0] == 'R') scanf("%d", &x), solve.Rotate(root, x);
		if (s[0] == 'G') solve.Get(root);
		if (s[0] == 'P') solve.Prev(root);
		if (s[0] == 'N') solve.Next(root);
		if (s[0] == 'I') scanf("%d", &x), solve.Insert(root, x);
	}
	return 0;
}


你可能感兴趣的:(HYSBZ 1269 文本编辑器editor)