记录编号 140538 评测结果 AAAAAAAAAA
题目名称 [NOI 2003]文本编辑器 最终得分 100
用户昵称 GravatarAsm.Def 是否通过 通过
代码语言 C++ 运行时间 0.797 s
提交时间 2014-11-22 18:11:16 内存使用 42.31 MiB
显示代码纯文本
#include <cstdio>
#include <iostream>
#include <cctype>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <assert.h>
#include <ctime>
using namespace std;
#if defined DEBUG
FILE *in = fopen("test", "r");
//#define out stdout
FILE *out = fopen("editor2003.out", "w");
#else
FILE *in = fopen("editor2003.in", "r");
FILE *out = fopen("editor2003.out", "w");
#endif
inline void getd(int &x){
	char c = fgetc(in);
	bool minus = 0;
	while(!isdigit(c))c = fgetc(in);
	x = c - '0';
	while(isdigit(c = fgetc(in)))x = x * 10 - '0' + c;
	if(minus)x = -x;
}
/*=====================================================*/
const int maxn = (1 << 21) + 3;
struct SPLAY{
	int key, size;
	SPLAY *son[2], *p;
	SPLAY(int k):key(k), size(0){son[0] = son[1] = p = NULL;}
	SPLAY():size(1){}
	void rot(), splay(SPLAY*), next(), prev(), get();
	SPLAY *find(int k){
		assert(k && k <= size);
		if(size == 1)return this;
		if(k <= son[0]->size) return son[0]->find(k);
		if((k -= son[0]->size) == (bool)key) return this;
		return son[1]->find(k - (key>0));
	}
}nil(0), ptr(0), Pool[maxn];
int it = 0;
char buf[maxn];

inline void update(SPLAY *x){x->size = x->son[0]->size + x->son[1]->size + 1;}
inline bool valid(int ch){return ch < 127 && ch > 31;}

inline SPLAY *newT(char *str, int len){
	int mid = len >> 1;
	SPLAY *ans = Pool + it++;
	ans->key = str[mid];
	ans->size = len;
	ans->p = ans->son[0] = ans->son[1] = &nil;
	if(mid) ans->son[0] = newT(str, mid), ans->son[0]->p = ans;
	if(len-mid-1) ans->son[1] = newT(str+mid+1, len-mid-1),
			ans->son[1]->p = ans;
	return ans;
}

void SPLAY::rot(){
	bool lr = (this == p->son[1]);
	bool plr = (p == p->p->son[1]);
	p->son[lr] = son[lr^1], son[lr^1]->p = p, son[lr^1] = p;
	p = p->p, p->son[plr] = this, son[lr^1]->p = this;
	update(son[lr^1]);
}

void SPLAY::splay(SPLAY *x){
	assert(this != &nil && x != &nil);
	while(x->p != this){
		if(x->p->p != this){
			bool lr = (x==x->p->son[1]);
			bool plr = (x->p==x->p->p->son[1]);
			if(lr == plr)
				x->p->rot();
			else x->rot();
		}
		x->rot();
	}
	update(x);
}

void SPLAY::get(){
	assert(this != &nil);
	if(son[0] != &nil) son[0]->get();
	if(key) fputc(key, out);
	if(son[1] != &nil) son[1]->get();
}

SPLAY *merge(SPLAY *a, SPLAY *b){
	if(a == &nil)return b;
	if(b == &nil)return a;
	SPLAY *x = b->find(1);
	b->p->splay(x);
	a->p = x; x->son[0] = a;
	x->size += a->size;
	return x;
}

void split(SPLAY *x, int k, SPLAY* &a, SPLAY* &b){
	assert(x->size >= k);
	if(k == 0){
		a = &nil; b = x;
		return;
	}
	a = x->find(k); x->p->splay(a);
	b = a->son[1]; b->p = &nil;
	a->size -= b->size; a->son[1] = &nil;
}

void SPLAY::next(){
	assert(son[1] != &nil);
	SPLAY *x = son[1]->find(1);
	splay(x);
	x->son[0] = son[0];
	x->size = son[0]->size + 1;
	son[0]->p = x;
	son[0] = x;
	son[1] = x->son[1];
	x->son[1] = &nil;
	son[1]->p = this;
}

void SPLAY::prev(){
	assert(son[0] != &nil);
	SPLAY *x = son[0]->find(son[0]->size);
	splay(x);
	x->son[1] = son[1];
	x->size = son[1]->size + 1;
	son[1]->p = x;
	son[1] = x;
	son[0] = x->son[0];
	x->son[0] = &nil;
	son[0]->p = this;
	
}

inline void Move(){
	int k; getd(k);
	SPLAY *t = merge(ptr.son[0], ptr.son[1]);
	split(t, k, ptr.son[0], ptr.son[1]);
	ptr.son[0]->p = ptr.son[1]->p = &ptr;
}

inline void Insert(){
	int len, i; getd(len);
	for(i = 0;i < len;++i)
		while(!valid(buf[i] = fgetc(in)));
	if(ptr.son[1] == &nil){
		ptr.son[1] = newT(buf, len);
		ptr.son[1]->p = &ptr;
		ptr.size += ptr.son[1]->size;
		return;
	}
	SPLAY *t = ptr.son[1]->find(1);
	ptr.splay(t);
	t->son[0] = newT(buf, len);
	ptr.son[1]->p = &ptr;
	t->son[0]->p = t;
	update(t);
	update(&ptr);
}

inline void Del(){
	int k; getd(k);
	SPLAY *a, *b;
	split(ptr.son[1], k, a, b);
	ptr.son[1] = b;
	b->p = &ptr;
	update(&ptr);
}

inline void Get(){
	int k; getd(k);
	if(ptr.son[1]->size == k)
		ptr.son[1]->get();
	else{
		ptr.splay(ptr.son[1]->find(k+1));
		ptr.son[1]->son[0]->get();
	}
	fputc('\n', out);
}

int main(){
	ptr.p = ptr.son[0] = ptr.son[1] = &nil;
	int T, ord;
	getd(T);
	while(T--){
		while(!isalpha(ord = fgetc(in)));
		while(isalpha(fgetc(in)));
		switch(ord){
			case 'M':Move();break;
			case 'I':Insert();break;
			case 'D':Del();break;
			case 'G':Get();break;
			case 'P':ptr.prev();break;
			default :ptr.next();break;
		}
	}
	#if defined DEBUG
	cout << endl << (double)clock() / CLOCKS_PER_SEC <<" sec" << endl;
	#endif
	return 0;
}