标签:bzoj1503 bzoj splay 伸展树 noi2003
题目大意:维护一种数据结构,它可以:
1.移动光标
2.在光标之后插入一段字符串
3.删除光标之后的n个字符
4.输出光标之后的n个字符
5.移动光标
思路:Splay,没什么特别的。但是有几个需要注意的地方。1.题中说:delete操作不会越界。但是其实有可能会越界,比如样例就越界了。。
2.输出的时候一定不要偷懒。我刚开始写的时候就把输出写成nlogn输出的了,然后果断T了吗,我还以为是哪里死循环了,结果是这里被卡了!以后再也不偷懒随便加logn了。。。
CODE:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MAX (1 << 22|100) using namespace std; struct Complex{ char c; int size; Complex *son[2],*father; void Combine(Complex *a,bool dir) { son[dir] = a; a->father = this; } bool Check() { return father->son[1] == this; } void PushUp() { size = son[0]->size + son[1]->size + 1; } }*nil = new Complex(),*root; void Pretreatment(); Complex *BuildTree(int l,int r); Complex *Kth(Complex *a,int k); Complex *NewComplex(char val); inline void Rotate(Complex *a,bool dir); inline void Splay(Complex *a,Complex *aim); void Print(Complex *a); char src[MAX]; int asks,now; char s[MAX]; int main() { Pretreatment(); cin >> asks; for(int x,i = 1;i <= asks; ++i) { scanf("%s",s); if(s[0] == 'M') scanf("%d",&now); else if(s[0] == 'I') { scanf("%d",&x); for(int j = 1;j <= x; ++j) while(scanf("%c",&src[j]),src[j] < 32); Splay(Kth(root,now + 1),nil); Splay(Kth(root,now + 2),root); root->son[1]->Combine(BuildTree(1,x),false); root->son[1]->PushUp(); root->PushUp(); } else if(s[0] == 'D') { scanf("%d",&x); Splay(Kth(root,now + 1),nil); Splay(Kth(root,min(root->size,now + x + 2)),root); root->son[1]->son[0] = nil; root->son[1]->PushUp(); root->PushUp(); } else if(s[0] == 'G') { scanf("%d",&x); Splay(Kth(root,now + 1),nil); Splay(Kth(root,min(now + x + 2,root->size)),root); Print(root->son[1]->son[0]); puts(""); } else if(s[0] == 'P') --now; else ++now; } return 0; } void Pretreatment() { root = BuildTree(1,2); root->father = nil; nil->father = nil->son[0] = nil->son[1] = nil; nil->size = 0; } Complex *BuildTree(int l,int r) { if(l > r) return nil; int mid = (l + r) >> 1; Complex *re = NewComplex(src[mid]); re->Combine(BuildTree(l,mid - 1),false); re->Combine(BuildTree(mid + 1,r),true); re->PushUp(); return re; } Complex *Kth(Complex *a,int k) { if(k <= a->son[0]->size) return Kth(a->son[0],k); k -= a->son[0]->size; if(k == 1) return a; return Kth(a->son[1],k - 1); } Complex *NewComplex(char val) { Complex *re = new Complex(); re->c = val; re->size = 1; re->son[0] = re->son[1] = nil; return re; } inline void Rotate(Complex *a,bool dir) { Complex *f = a->father; f->son[!dir] = a->son[dir]; f->son[!dir]->father = f; a->son[dir] = f; a->father = f->father; f->father->son[f->Check()] = a; f->father = a; f->PushUp(); if(root == f) root = a; } inline void Splay(Complex *a,Complex *aim) { while(a->father != aim) { if(a->father->father == aim) Rotate(a,!a->Check()); else if(!a->father->Check()) { if(!a->Check()) Rotate(a->father,true),Rotate(a,true); else Rotate(a,false),Rotate(a,true); } else { if(a->Check()) Rotate(a->father,false),Rotate(a,false); else Rotate(a,true),Rotate(a,false); } } a->PushUp(); } void Print(Complex *a) { if(a == nil) return ; Print(a->son[0]); putchar(a->c); Print(a->son[1]); }
BZOJ 1507 NOI 2003 Editor Splay
标签:bzoj1503 bzoj splay 伸展树 noi2003
原文地址:http://blog.csdn.net/jiangyuze831/article/details/39723487