文艺平衡树

原题链接:https://www.luogu.org/problemnew/show/P3391

splay处理区间问题板子,备用。

等待补充详细解释中。

#include<cstdio>
void read(int &y)
{
    y=0;char x=getchar();
    while(x<'0'||x>'9') x=getchar();
    while(x>='0'&&x<='9')
    {
        y=y*10+x-'0';
        x=getchar();
    }
}
struct tree
{
    int ch[2],s,v,f,w;
}tr[100005];
int n,m,rot,tot;
void set(int k,int x,int z)
{
    tr[k].ch[0]=tr[k].ch[1]=0;
    tr[k].s=0;tr[k].v=x;
    tr[k].w=z;
}
void update(int k)
{
    tr[k].s=tr[tr[k].ch[0]].s+tr[tr[k].ch[1]].s+1;
}
void pushdown(int k)
{
    if(tr[k].f)
    {
        tr[tr[k].ch[0]].f^=1;
        tr[tr[k].ch[1]].f^=1;
        tr[k].f=0;
        int t=tr[k].ch[0];
        tr[k].ch[0]=tr[k].ch[1];
        tr[k].ch[1]=t;
    }
}
void rotate(int x)
{
    int y=tr[x].w;
    int z=tr[y].w;
    int k=(tr[y].ch[1]==x);
    if(tr[z].ch[1]==y) tr[z].ch[1]=x;
    else tr[z].ch[0]=x; 
    tr[x].w=z;
    tr[y].ch[k]=tr[x].ch[k^1];
    tr[tr[x].ch[k^1]].w=y;
    tr[x].ch[k^1]=y;
    tr[y].w=x;
    update(y);update(x);
}
void splay(int x,int a)
{
    while(tr[x].w!=a)
    {
        int y=tr[x].w;
        int z=tr[y].w;
        if(z!=a)
        {
            int p1=(tr[z].ch[1]==y);
            int p2=(tr[y].ch[1]==x);
            if(p1^p2) rotate(x);
            else rotate(y);
        }
        rotate(x);
    }
    if(a==0) rot=x;
    
}
void insert(int x)
{
    int t=rot,nxt=0;
    while(t)
    {
        nxt=t;
        if(x>tr[t].v) t=tr[t].ch[1];
        else t=tr[t].ch[0];
    }
    t=++tot;
    if(nxt)
    {
        if(x>tr[nxt].v) tr[nxt].ch[1]=t;
        else tr[nxt].ch[0]=t;
    }
    set(t,x,nxt);
    splay(t,0);
}
int kth(int k)
{
    int t=rot;
    while(1)
    {
        pushdown(t);
        if(tr[tr[t].ch[0]].s>=k) t=tr[t].ch[0];
        else if(tr[tr[t].ch[0]].s+1==k) return t;
        else
        {
            k-=tr[tr[t].ch[0]].s+1;
            t=tr[t].ch[1];
        }
    }
}
void print(int t)
{
    pushdown(t);
    if(tr[t].ch[0]) print(tr[t].ch[0]);
    if(tr[t].v>1&&tr[t].v<n+2) printf("%d ",tr[t].v-1);
    if(tr[t].ch[1]) print(tr[t].ch[1]);
}
void solve(int l,int r)
{
    l=kth(l);
    r=kth(r+2);
    splay(l,0);splay(r,l);
    tr[tr[tr[rot].ch[1]].ch[0]].f^=1;
}
int main()
{
    read(n);read(m);
    int l,r;
    for(int i=1;i<=n+2;i++) insert(i);
    while(m--)
    {
        read(l);read(r);
        solve(l,r);
    }
    print(rot);
    return 0;
}
原文地址:https://www.cnblogs.com/zeroform/p/8340122.html