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;
}

浙公网安备 33010602011771号