bzoj 3223 文艺平衡树 Splay

来源:互联网 发布:重庆网络知识竞赛 编辑:程序博客网 时间:2024/05/29 03:59

Splay维护区间翻转裸题,但还是调了很长时间。

#include<iostream>#include<cstdio>#define maxn 100005using namespace std;int rev[maxn],fa[maxn],ch[maxn][2];int sz[maxn];int root;bool dir(int x){return x==ch[fa[x]][1];}void up(int x){sz[x]=sz[ch[x][1]]+sz[ch[x][0]]+1;}void rotate(int x){    int y=fa[x],z=fa[y];    bool b=dir(x);int a=ch[x][!b];    if(z!=0)ch[z][dir(y)]=x;    else    root=x;    fa[x]=z;ch[x][!b]=y;    fa[y]=x;ch[y][b]=a;    if(a) fa[a]=y;    up(y);up(x);}int S[maxn],tot;void down(int x){    if(rev[x])    {        rev[ch[x][0]]^=1;        rev[ch[x][1]]^=1;        rev[x]=0;        swap(ch[x][0],ch[x][1]);    }}void splay(int x,int e){    for(int i=x;i;i=fa[i])        S[++tot]=i;    while(tot) down(S[tot--]);    while(fa[x]!=e)    {        int y=fa[x],z=fa[y];        if(fa[y]==e) rotate(x);        else        {            bool b=dir(x),c=dir(y);            if(b^c) {rotate(y);rotate(x);}            else    {rotate(x);rotate(x);}        }    }}int n,m;int s,t;void dfs(int x){    down(x);    if(ch[x][0])dfs(ch[x][0]);    if(x!=s&&x!=t)    printf("%d ",x-1);    if(ch[x][1])dfs(ch[x][1]);}void read(int &a){    a=0;char c=getchar();    while(c<'0'||c>'9')        c=getchar();    while(c>='0'&&c<='9')    {        a*=10;a+=c-'0';        c=getchar();    }}int find(int x,int k){    down(x);    if(sz[ch[x][0]]>=k)        return find(ch[x][0],k);    if(sz[ch[x][0]]==k-1)        return x;    return find(ch[x][1],k-sz[ch[x][0]]-1);}int main(){    read(n);read(m);    s=1;t=n+2;    for(int i=2;i<=n+1;i++)    {        fa[i]=i+1;        ch[i][0]=i-1;        sz[i]=i;    }    fa[1]=2;sz[1]=1;    fa[n+2]=0;ch[n+2][0]=n+1;root=n+2;sz[n+2]=n+2;    int l,r;    for(int i=1;i<=m;i++)    {        read(l);read(r);        l++;r++;        if(l==r) continue;        int t1=find(root,r+1);        int t2=find(root,l-1);        splay(t1,0);        splay(t2,root);        rev[ch[ch[root][0]][1]]^=1;    }    dfs(root);    return 0;}
6 0