BZOJ1507 [NOI2003]Editor 【splay】

1507: [NOI2003]Editor

Time Limit: 5 Sec  Memory Limit: 162 MB
Submit: 4129  Solved: 1660
[Submit][Status][Discuss]

Description

Input

输入文件editor.in的第一行是指令条数t,以下是需要执行的t个操作。其中: 为了使输入文件便于阅读,Insert操作的字符串中可能会插入一些回车符,请忽略掉它们(如果难以理解这句话,可以参考样例)。 除了回车符之外,输入文件的所有字符的ASCII码都在闭区间[32, 126]内。且行尾没有空格。 这里我们有如下假定:  MOVE操作不超过50000个,INSERT和DELETE操作的总个数不超过4000,PREV和NEXT操作的总个数不超过200000。  所有INSERT插入的字符数之和不超过2M(1M=1024*1024),正确的输出文件长度不超过3M字节。  DELETE操作和GET操作执行时光标后必然有足够的字符。MOVE、PREV、NEXT操作必然不会试图把光标移动到非法位置。  输入文件没有错误。 对C++选手的提示:经测试,最大的测试数据使用fstream进行输入有可能会比使用stdio慢约1秒。

Output

输出文件editor.out的每行依次对应输入文件中每条GET指令的输出。

Sample Input

15
Insert 26
abcdefghijklmnop
qrstuv wxy
Move 15
Delete 11
Move 5
Insert 1
^
Next
Insert 1
_
Next
Next
Insert 4
.\/.
Get 4
Prev
Insert 1
^
Move 0
Get 22

Sample Output

.\/.
abcde^_^f.\/.ghijklmno

和之前写过的一道省选题几乎一样【少了个翻转,简单些】

splay水过

【附上TLE,MLE,RE,WA,AC崩溃路程QAQ】


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long int
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define isr(u) (e[e[u].f].ch[1] == u)
#define ls e[u].ch[0]
#define rs e[u].ch[1]
#define sizl(u) (e[e[u].ch[0]].siz)
using namespace std;
const int maxn = 1000005,maxm = 3000005,INF = 1000000000;
inline int RD(){
	int out = 0,flag = 1; char c = getchar();
	while (c < 48 || c > 57) {if (c == '-') flag = -1; c = getchar();}
	while (c >= 48 && c <= 57) {out = (out << 1) + (out << 3) + c - '0'; c = getchar();}
	return out * flag;
}
char cmd[105],s[maxm];
int siz = 0,pos = 0,rt = 0;
struct node{char c; int ch[2],f,siz;}e[maxm];
inline void pup(int u) {e[u].siz = sizl(u) + 1 + e[rs].siz;}
inline void spin(int u){
	int s = isr(u),fa = e[u].f;
	e[u].f = e[fa].f; if (e[fa].f) e[e[fa].f].ch[isr(fa)] = u;
	e[fa].ch[s] = e[u].ch[s ^ 1]; if (e[u].ch[s ^ 1]) e[e[u].ch[s ^ 1]].f = fa;
	e[fa].f = u; e[u].ch[s ^ 1] = fa;
	pup(fa); pup(u);
}
inline void splay(int u,int v = 0){
	for (; e[u].f != v; spin(u))
		if (e[e[u].f].f != v) spin((isr(u) ^ isr(e[u].f)) ? u : e[u].f);
	if (!v) rt = u;
}
inline void Kth(int k,int p){
	int u = rt;
	while (true){
		if (sizl(u) >= k) u = ls;
		else if (sizl(u) + 1 == k) {splay(u,p);break;}
		else k -= sizl(u) + 1,u = rs;
	}
}
int build(int fa,int l,int r){
	if (l > r) return 0;
	int u = ++siz; e[u].f = fa; e[u].siz = 1;
	int mid = l + r >> 1; e[u].c = s[mid];
	if (l == r) return u;
	e[u].ch[0] = build(u,l,mid - 1);
	e[u].ch[1] = build(u,mid + 1,r);
	pup(u);
	return u;
}
void Insert(){
	int n = RD(); char c;
	Kth(pos + 1,0); Kth(pos + 2,rt);
	for (int i = 1; i <= n; i++){c = getchar(); while (c < 32 || c > 126) c = getchar(); s[i] = c;}
	e[e[rt].ch[1]].ch[0] = build(e[rt].ch[1],1,n);
	pup(e[rt].ch[1]); pup(rt);
}
void Print(int u){
	if (!u) return;
	Print(ls); printf("%c",e[u].c); Print(rs);
}
void Delete(){
	int n = RD();
	Kth(pos + 1,0); Kth(pos + n + 2,rt);
	e[e[rt].ch[1]].ch[0] = 0;
	pup(e[rt].ch[1]); pup(rt);
}
void Get(){
	int n = RD();
	Kth(pos + 1,0); Kth(pos + n + 2,rt);
	Print(e[e[rt].ch[1]].ch[0]); printf("\n");
}
int main(){
	//freopen("out.txt","w",stdout);
	e[siz = 2].f = 1; e[rt = 1].ch[1] = siz; e[rt].siz = 2; e[siz].siz = 1;
	int T = RD();
	while (T--){
		scanf("%s",cmd);
		switch(cmd[0]){
			case 'M':pos = RD();break;
			case 'I':Insert();break;
			case 'D':Delete();break;
			case 'G':Get();break;
			case 'P':pos--;break;
			case 'N':pos++;break;
			default:break;
		}
	}
	return 0;
}


posted @ 2017-12-07 17:04  Mychael  阅读(160)  评论(0编辑  收藏  举报