您的位置:首页 > 其它

1269: [AHOI2006]文本编辑器editor

2017-12-16 10:40 197 查看

1269: [AHOI2006]文本编辑器editor

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 4718  Solved: 1807
[Submit][Status][Discuss]

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操作不会把光标移动到非法位置。 输入文件没有错误。

 

Source

鸣谢seter重新制作数据

 

分析

纪念:我的第一颗splay树!!!

写的有点丑,splay恰好都支持这些功能,所以用的是splay。。

code

 

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<map>
#include<queue>

using namespace std;

const int N = 2000100;

int ch
[2],fa
,data
,tag
,siz
;
int t[100100],st[100100],top;
int tn,Root;

inline int read() {
int x = 0,f = 1;char ch = getchar();
for (; ch<'0'||ch>'9'; ch = getchar())
if (ch=='-') f = -1;
for (; ch>='0'&&ch<='9'; ch = getchar())
x = x*10+ch-'0';
return x * f;
}
inline int son(int x) {
return x==ch[fa[x]][1];
}
inline void pushup(int x) {
siz[x] = siz[ch[x][0]] + siz[ch[x][1]] + 1;
}
inline void pushdown(int x) {
if (tag[x]) {
tag[ch[x][0]] ^= 1;tag[ch[x][1]] ^= 1;
swap(ch[x][0],ch[x][1]);
tag[x] ^= 1;
}
}
inline void rotate(int x) {
int y = fa[x],z = fa[y],b = son(x),c = son(y),a = ch[x][!b];
if (z) ch[z][c] = x;else Root = x;fa[x] = z;
ch[x][!b] = y;fa[y] = x;
ch[y][b] = a;if (a) fa[a] = y;
pushup(y);pushup(x);
}
inline void splay(int x,int rt) {
/* top = 0;int p = x;
while (p) st[++top] = p,p = fa

; while (top) pushdown(st[top]),top--;*/ // 这个地方在查找是已经下传了 while (fa[x] != rt) { int y = fa[x],z = fa[y]; if (z==rt) rotate(x); else { if (son(x)==son(y)) rotate(y),rotate(x); else rotate(x),rotate(x); } } } inline int getkth(int k) { int p = Root; while (true) { pushdown(p); if (k==siz[ch[p][0]] + 1) return p; if (ch[p][0] && k <= siz[ch[p][0]]) p = ch[p][0]; else { k -= ((ch[p][0] ? siz[ch[p][0]] : 0) + 1); p = ch[p][1]; } } } int build(int l,int r) { if (l > r) return 0; int mid = (l + r) >> 1; int tmp = build(l,mid-1); fa[tmp] = mid;ch[mid][0] = tmp; tmp = build(mid+1,r); fa[tmp] = mid;ch[mid][1] = tmp; pushup(mid); return mid; } inline void Insert(int p) { int x = read(); char c; for (int i=1; i<=x; ++i) {c = getchar();data[++tn] = (int)c;} int tmp = build(tn-x+1,tn); int L = getkth(p),R = getkth(p + 1); splay(L,0);splay(R,L); fa[tmp] = R;ch[R][0] = tmp; pushup(R);pushup(L); } inline void Delete(int p,int x) { int L = getkth(p),R = getkth(p+x+1); splay(L,0);splay(R,L); ch[R][0] = 0;fa[ch[R][0]] = 0; pushup(R);pushup(L); } inline void rever(int l,int x) { int r = l + x + 1; int L = getkth(l),R = getkth(r); splay(L,0);splay(R,L); tag[ch[R][0]] ^= 1; } int main() { int n = read(),now = 1,x; char s[20]; Root = 1;ch[1][1] = 2;fa[2] = 1;siz[1] = 2;siz[2] = 1;tn = 2; while (n--) { scanf("%s",s); if (s[0]=='I') Insert(now); else if (s[0]=='D') Delete(now,read()); else if (s[0]=='M') { x = read();now = x + 1; } else if (s[0]=='R') rever(now,read()); else if (s[0]=='G') { x = getkth(now + 1);printf("%c\n",data[x]); } else if (s[0]=='P') now --; else if (s[0]=='N') now ++; } return 0; }

[p] 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: