splay模板基本操作
Splay模板指针实现
splay中序遍历维护原序列下标的顺序,翻转后这个顺序会改变,但是splay中第x个数代表变换后序列中第x个数
这样就可以直接查找变换后的序列
重在代码
文艺平衡树
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #define INF 0x3f3f3f3f using namespace std; struct node { node *ls,*rs,*fa; node(int x); void pushdown(); void pushup(); int rev,num,sz; }*null=new node(0),*root=null;//空指针可以直接建出来,NULL容易出错 node::node(int x) { ls=rs=fa=null; sz=rev=0; num=x; } void node ::pushdown() { if(rev)//rev翻转标记,表示子节点是否翻转 { ls->rev^=1; rs->rev^=1; swap(ls->ls,ls->rs); swap(rs->ls,rs->rs); rev=0; } } void node :: pushup() { sz=ls->sz+rs->sz+1; } struct Splay { void up(node *&y,node *&x) { if(y==y->fa->ls) y->fa->ls=x; else if(y==y->fa->rs) y->fa->rs=x; y->fa=x; y->pushup(); if(y==root) root=x; } void zig(node *x)//右旋 { node *y=x->fa; y->pushdown();x->pushdown();//下传标记,顺序不能变,先传父节点,再传儿子节点 y->ls=x->rs; x->rs->fa=y; x->rs=y; x->fa=y->fa; up(y,x); } void zag(node *x)//左旋 { node *y=x->fa; y->pushdown();x->pushdown(); y->rs=x->ls; x->ls->fa=y; x->ls=y; x->fa=y->fa; up(y,x); } void splay(node *x,node *tar)//把x旋到tar的子节点 { while(1){ node *y=x->fa,*z=y->fa; if(y==tar) break; if(z==tar){ if(x==y->ls) zig(x); else zag(x); break; } if(x==y->ls){ if(y==z->ls) zig(y);//一字型先旋y zig(x); } else{ if(y==z->rs) zag(y); zag(x); } } x->pushup(); } node* findx(node *x,int y)//查找第y个数,y不是权值,是序列中的顺序 { while(1){ x->pushdown(); if(y<=x->ls->sz) x=x->ls; else { y-=x->ls->sz; if(y==1) break; y--; x=x->rs; } } return x; } void find(int x,int y)//找到要操作的区间 { node *t1=findx(root,x); node *t2=findx(root,y); splay(t1,null); splay(t2,root); } void insert(node *&x,int y,node *z)//插入一个权值为y的数 { if(x==null){ x=new node(y); x->fa=z; splay(x,null); return ; } x->pushdown(); insert(x->rs,y,x); } }sp; int n,m,x,y; int main() { freopen("sph.in","r",stdin); freopen("sph.out","w",stdout); scanf("%d%d",&n,&m); sp.insert(root,INF,null);//建立0和n+1节点,方便翻转 for(int i=1;i<=n;i++) sp.insert(root,i,null); sp.insert(root,INF,null); for(int i=1;i<=m;i++){ scanf("%d%d",&x,&y); sp.find(x,y+2);//有0节点,注意下区间,操作区间【x,y】,把x-1旋到根,y+1旋到x-1的右儿子
node *tmp=root->rs->ls; tmp->rev^=1; swap(tmp->ls,tmp->rs); } for(int i=2;i<=n+1;i++) printf("%d ",sp.findx(root,i)->num); // while(1); return 0; }