bzoj 3223 splay模板题3

水题。。。貌似理解splay怎么维护数列了。。。

每个点维护一个size,它的位置就是它的size,区间翻转的话可以打标记,find的时候push_down,交换左右子树。

 #include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define N 100005
#define lc(x) ch[x][0]
#define rc(x) ch[x][1]
using namespace std;
int cnt;
int k[N];
int size[N];
int lazy[N];
int ch[N][];
int dai[N];int fa[N];
int n,m;int root;
void push_up(int x)
{
size[x]=size[ch[x][]]+size[ch[x][]]+;
return ;
}
void rotate(int p)
{
int q=fa[p],y=fa[q],x=(ch[q][]==p);
ch[q][x]=ch[p][x^];fa[ch[p][x^]]=q;
ch[p][x^]=q;fa[q]=p;fa[p]=y;
if(y)
{
if(q==ch[y][])ch[y][]=p;else ch[y][]=p;
}
push_up(q);push_up(p);
return ;
}
void splay(int x,int pos)
{
for(int y;y=fa[x];rotate(x))
{
if(y==pos)break;
if(fa[y]!=pos)
{
if((ch[fa[y]][]==y&&ch[y][]==x)||(ch[fa[y]][]==y&&ch[y][]==x))rotate(y);
else rotate(x);
}
}
if(!pos)root=x;
}
void push_down(int x)
{
if(lazy[x])
{
lazy[x]=;
lazy[ch[x][]]^=;lazy[ch[x][]]^=;
swap(ch[x][],ch[x][]);
}
}
int find(int k,int rank)
{
push_down(k);
int l=ch[k][];int r=ch[k][];
if(size[l]+==rank)return k;
else if(size[l]>=rank)return find(ch[k][],rank);
else return find(ch[k][],rank-size[l]-);
}
void dfs(int x)
{
push_down(x);
if(ch[x][])dfs(ch[x][]);
if(k[x]!=&&k[x]!=n+)printf("%d ",k[x]);
if(ch[x][])dfs(ch[x][]);
}
int main()
{
scanf("%d%d",&n,&m);
cnt=n+;root=;
for(int i=;i<=n+;i++)
{
ch[i+][]=i+;
fa[i+]=i+;
k[i+]=i;
size[i+]=n+2-i;
}ch[n+][]=;
for(int i=;i<=m;i++)
{
int t1,t2;
scanf("%d%d",&t1,&t2);
int x1=find(root,t1);int x2=find(root,t2+);
splay(x1,);splay(x2,x1);
lazy[ch[x2][]]^=;
}
dfs(root);
return ;
}
/*
5 1
1 4
*/
上一篇:Python之微信-微信机器人


下一篇:Redis学习笔记(1)-Key