洛谷3391文艺平衡树

区间旋转裸体,把一个区间翻转就是把这个区间对应的平衡树的所有节点的左右儿子交换(这个想想就明白了);

然后需要做的就是提取区间和打标记和传标记;

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=100010,inf=1e9;
struct node{
    int fa,l,r,p,v;
}tr[maxn];
int root,n,m,tot,siz[maxn],mar[maxn];
void newno(int dat,int fa){tr[++tot].v=dat;tr[tot].fa=fa;tr[tot].l=tr[tot].r=-1;siz[tot]=1;}
int change(int x){siz[x]=1;if(tr[x].l!=-1)siz[x]+=siz[tr[x].l];if(tr[x].r!=-1)siz[x]+=siz[tr[x].r];}
int getsiz(int x){if(x==-1)return 0;else return siz[x];}
void pushdown(int x){
    if(x==-1)return;
    if(mar[x]){
        if(tr[x].l!=-1)mar[tr[x].l]^=1;
        if(tr[x].r!=-1)mar[tr[x].r]^=1;
        swap(tr[x].l,tr[x].r);
        mar[x]=0;
    }
}
void rx(int x){
    int y=tr[x].fa,z=tr[y].fa;
    pushdown(y);pushdown(x);
    tr[y].l=tr[x].r;
    if(tr[x].r!=-1)tr[tr[x].r].fa=y;
    tr[x].fa=z;
    if(z!=-1){
        if(tr[z].l==y)tr[z].l=x;
        else tr[z].r=x;
    }
    tr[x].r=y;tr[y].fa=x;change(y);change(x);
}
void lx(int x){
    int y=tr[x].fa,z=tr[y].fa;
    pushdown(y);pushdown(x);
    tr[y].r=tr[x].l;
    if(tr[x].l!=-1)tr[tr[x].l].fa=y;
    tr[x].fa=z;
    if(z!=-1){
        if(tr[z].l==y)tr[z].l=x;
        else tr[z].r=x;
    }
    tr[x].l=y;tr[y].fa=x;change(y);change(x);
}
void splay(int x,int zz){
    while(tr[x].fa!=zz){
        int y=tr[x].fa,z=tr[y].fa;
        if(z==zz){
            if(tr[y].l==x)rx(x);else lx(x);
        }
        else{
            if(tr[z].l==y&&tr[y].l==x){rx(y);rx(x);}
            else if(tr[z].l==y&&tr[y].r==x){lx(x);rx(x);}
            else if(tr[z].r==y&&tr[y].r==x){lx(y);lx(x);}
            else {rx(x);lx(x);}
        }
    }
    if(zz==-1)root=x;
}
void bins(int x,int k,int dat){
    pushdown(x);
    if(k==1&&tr[x].l==-1){newno(dat,x);tr[x].l=tot;change(x);return;}
    if(k==2+getsiz(tr[x].l)&&tr[x].r==-1){newno(dat,x);tr[x].r=tot;change(x);return;}
    if(k<=1+getsiz(tr[x].l))bins(tr[x].l,k,dat);
    else bins(tr[x].r,k-getsiz(tr[x].l)-1,dat);
    change(x);
}
int fin(int k){
    int now=root;
    while(1){
        
        pushdown(now);
        if(k<=getsiz(tr[now].l))now=tr[now].l;
        else{
            k-=getsiz(tr[now].l)+1;
            if(!k)return now;
            now=tr[now].r;
        }
    }
}
void pri(int now){
    pushdown(now);
    if(tr[now].l!=-1)pri(tr[now].l);
    if(tr[now].v!=inf)printf("%d ",tr[now].v);
    if(tr[now].r!=-1)pri(tr[now].r);
}
int main(){
    int x,y;
    cin>>n>>m;
    newno(inf,-1);root=1;
    for(int i=1;i<=n;++i){
        bins(root,i+1,i);
        if(i%2==0)splay(tot,-1);
    }
    bins(root,n+2,inf);
    for(int i=1;i<=m;++i){
        scanf("%d%d",&x,&y);
        int x1=fin(x);
        int y1=fin(y+2);
        splay(x1,-1);splay(y1,x1);
        mar[tr[tr[root].r].l]^=1;
    }
    pri(root);
    system("pause");
    return 0;
}
原文地址:https://www.cnblogs.com/dibaotianxing/p/8094783.html