文艺平衡树

和Splay差不多,就是维护区间,把siz值为l-1+1与r+1+1的两个节点,将一个旋转到根,另一个旋转到根的右儿子上,则要修改的区间就是根的右孩子的左子树,直接打标记即可。
推荐:远航之曲dalao

//Writer : Hsz %WJMZBMR%tourist%hzwer
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <queue>
#include <map>
#include <set>
#include <stack>
#include <cctype>
#include <vector>
#include <cstdlib>
#include <algorithm>
#define LL long long
#define M(a,b) memset(a,b,sizeof a)
using namespace std;
const int inf=0x3fffffff;
int in()
{
    int x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9') {
        if(ch=='-')f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9') {
        x=(x<<3)+(x<<1)+ch-'0';
        ch=getchar();
    }
    return x*f;
}
void out(int x)
{
    int a[25],wei=0;
    if(x<0) putchar('-'),x=-x;
    for(; x; x/=10) a[++wei]=x%10;
    if(wei==0) {
        puts("0");
        return;
    }
    for(int j=wei; j>=1; --j) putchar('0'+a[j]);
    putchar(' ');
}
const int N=500005;
int data[N],n,m;
struct Splay {
    int root,fa[N],ch[N][2],siz[N],rev[N],tot,key[N];
    void pushup(int x) {
        siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1;
        return;
    }
    bool check(int x) {
        return x==ch[fa[x]][1];
    }
    void pushdown(int x) {
        if(rev[x]&&x) {
            swap(ch[x][0],ch[x][1]);
            rev[ch[x][0]]^=1,rev[ch[x][1]]^=1;
            rev[x]=0;
        }
        return;
    }
    void rotate(int x) {
        int k=check(x),f=fa[x],ff=fa[f];
        pushdown(f);pushdown(x);
        ch[f][k]=ch[x][k^1];
        fa[ch[x][k^1]]=f;
        ch[x][k^1]=f;
        fa[f]=x;
        fa[x]=ff;
        if(ff) ch[ff][ch[ff][1]==f]=x;
        pushup(f);
        pushup(x);
    }
    void splay(int x,int tar) {
        for(int f; (f=fa[x])!=tar; rotate(x)) {
            if(fa[f]!=tar)rotate(check(x)==check(f)?f:x);
        }
        if(!tar) root=x;
    }
    int fnd(int k) {
        int now=root;
        while(1) {
            pushdown(now);
            if(k<=siz[ch[now][0]]) now=ch[now][0];
            else {
                k-=siz[ch[now][0]]+1;
                if(!k) return now;
                now=ch[now][1];
            }
        }
    }
    int build(int f,int l,int r) {
        if(l>r)return 0;
        int mid=(l+r)>>1;
        int now=++tot;
        key[now]=data[mid],fa[now]=f;
        ch[now][0]=build(now,l,mid-1);
        ch[now][1]=build(now,mid+1,r);
        pushup(now);
        return now;
    }
    void print(int x) {
        pushdown(x);
        if(ch[x][0]) print(ch[x][0]);
        if(key[x]!=-inf&&key[x]!=inf) out(key[x]);
        if(ch[x][1]) print(ch[x][1]);
    }
} SBT;

int main()
{
    n=in(),m=in();
    for(int i=1; i<=n; i++) data[i+1]=i;
    data[1]=-inf;
    data[n+2]=inf;
    SBT.root=SBT.build(0,1,n+2);
    for(int i=1,l,r; i<=m; i++) {
        l=in(),r=in();
        int x=SBT.fnd(l),y=SBT.fnd(r+2);
        SBT.splay(x,0);
        SBT.splay(y,x);
        SBT.rev[SBT.ch[SBT.ch[SBT.root][1]][0]]^=1;
    }
    SBT.print(SBT.root);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/sdfzhsz/p/9181483.html