Splay作为二叉平衡树与其他二叉平衡树不同的是,Splay能够支持区间操作。最然可持续化Treap也可以做到,但是代码量实在是难以同日而语。
放一个模板,只支持区间翻转。想看其他操作的可以看我的 维修数列 的博客:http://blog.csdn.net/jiangyuze831/article/details/39098481
PS:还是1A的,有点小开心……
CODE:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; struct Complex{ int val,size; bool reverse; Complex *son[2],*father; bool Check() { return father->son[1] == this; } void Combine(Complex *a,bool dir) { son[dir] = a; a->father = this; } void Reverse() { reverse ^= 1; swap(son[0],son[1]); } }none,*nil = &none,*root = nil; int cnt,asks; int last; Complex *BuildTree(int l,int r); Complex *NewComplex(Complex *f,int x); Complex *FindK(Complex *a,int k); inline void Rotate(Complex *a,bool dir); inline void Splay(Complex *a,Complex *aim); inline void Work(int x,int y); inline void PushUp(Complex *a); inline void PushDown(Complex *a); void Print(Complex *a); int main() { cin >> cnt >> asks; root = BuildTree(0,cnt + 1); root->father = nil; for(int x,y,i = 1;i <= asks; ++i) { scanf("%d%d",&x,&y); Work(x,y); } last = FindK(root,cnt + 1)->val; Print(root); return 0; } Complex *NewComplex(Complex *f,int val) { Complex *re = new Complex(); re->father = f; re->val = val; re->son[0] = re->son[1] = nil; re->reverse = false; return re; } Complex *BuildTree(int l,int r) { if(l > r) return nil; int mid = (l + r) >> 1; Complex *re = NewComplex(re,mid); re->Combine(BuildTree(l,mid - 1),false); re->Combine(BuildTree(mid + 1,r),true); PushUp(re); return re; } Complex *FindK(Complex *a,int k) { PushDown(a); if(k <= a->son[0]->size) return FindK(a->son[0],k); k -= a->son[0]->size; if(k == 1) return a; return FindK(a->son[1],k - 1); } inline void Rotate(Complex *a,bool dir) { Complex *f = a->father; PushDown(f),PushDown(a); 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; PushUp(f); 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); } } } PushUp(a); } inline void Work(int x,int y) { x++,y++; Splay(FindK(root,x - 1),nil); Splay(FindK(root,y + 1),root); root->son[1]->son[0]->Reverse(); } inline void PushUp(Complex *a) { if(a == nil) return ; a->size = a->son[0]->size + a->son[1]->size + 1; } inline void PushDown(Complex *a) { if(a->reverse) { a->son[0]->Reverse(); a->son[1]->Reverse(); a->reverse = false; } } void Print(Complex *a) { if(a == nil) return ; PushDown(a); Print(a->son[0]); if(a->val && a->val != cnt + 1) { printf("%d",a->val); if(a->val != last) putchar(' '); } Print(a->son[1]); }