Duan2baka的Splay模板!

来源:互联网 发布:无限透支黑卡 知乎 编辑:程序博客网 时间:2024/06/06 06:46

BZOJ[3223] Tyvj 1729 文艺平衡树
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3223

Splay区间翻转

代码如下:

#include<algorithm>#include<ctype.h>#include<cstdio>using namespace std;inline int read(){    int x=0,f=1;char c;    do c=getchar(),f=c=='-'?-1:f; while(!isdigit(c));    do x=(x<<3)+(x<<1)+c-'0',c=getchar(); while(isdigit(c));    return x*f;}struct Node{    Node *ch[2],*fa;    int x,siz;bool b;    Node(int);    void Pushdown();    inline int dir(){        if(fa->ch[0]==this) return 0;        if(fa->ch[1]==this) return 1;        return -1;    }    inline void maintain(){        siz=ch[0]->siz+ch[1]->siz+1;        return;    }    inline int cmp(int k){        if(k==ch[0]->siz+1) return -1;        return k<=ch[0]->siz?0:1;    }}*null,*root;Node::Node(int _):x(_){    ch[0]=ch[1]=fa=null;    siz=1;}inline void Node::Pushdown(){    if(!b) return;    swap(ch[0],ch[1]);    b=false;    if(ch[0]!=null) ch[0]->b^=1;    if(ch[1]!=null) ch[1]->b^=1;}int n,m,x,y;Node *K_th(Node *x,int k){    x->Pushdown();    int d=x->cmp(k);    if(!~d) return x;    return K_th(x->ch[d],k-(d?x->ch[0]->siz+1:0));}inline void Rotate(Node *x,int d){    Node *k=x->ch[d^1];    x->ch[d^1]=k->ch[d];    if(k->ch[d]!=null) k->ch[d]->fa=x;    k->ch[d]=x;    if(x->fa!=null) x->fa->ch[x->dir()]=k;    k->fa=x->fa;x->fa=k;    x->maintain();k->maintain();}void Debug(Node *x){///调试,输出前序遍历    printf("%d \n",x->x);    if(x->ch[0]!=null) Debug(x->ch[0]);    if(x->ch[1]!=null) Debug(x->ch[1]);}void Debug1(Node *x){///调试,输出中序遍历    if(x->ch[0]!=null) Debug1(x->ch[0]);    printf("%d \n",x->x);    if(x->ch[1]!=null) Debug1(x->ch[1]);}inline void Splay(Node *x,Node *y){///把x旋转到y的儿子上    while(x->fa!=y){        if(x->fa->fa!=y)            if(x->dir()==x->fa->dir()) Rotate(x->fa->fa,x->dir()^1);        Rotate(x->fa,x->dir()^1);    }    x->maintain();    if(y==null) root=x;}inline void Reverse(int x,int y){    if(x==y) return;    Node *a=K_th(root,x);Splay(a,null);    Node *b=K_th(root,y+2);Splay(b,root);    root->ch[1]->ch[0]->b^=1;}void Build(Node *Fa,Node *&x,int l,int r){    if(l>r) return;    int mid=l+r>>1;    x=new Node(mid);    x->fa=Fa;    Build(x,x->ch[0],l,mid-1);Build(x,x->ch[1],mid+1,r);    x->maintain();}int main(){    null=new Node(-1);    null->b=null->siz=0;    null->ch[0]=null->ch[1]=null->fa=null;    root=null;    n=read();m=read();    Build(null,root,0,n+1);    for(int i=1;i<=m;i++){        x=read();y=read();        Reverse(x,y);    }    for(int i=2;i<=n+1;i++)        printf("%d ",K_th(root,i)->x);return 0;}