P3391 【模板】文艺平衡树

题目链接:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define re register
const int N=1e6+10;
void read(int &a)
{
    a=0;int d=1;char ch;
    while(ch=getchar(),ch>'9'||ch<'0')
        if(ch=='-')
            d=-1;
    a=ch^48;
    while(ch=getchar(),ch>='0'&&ch<='9')
        a=(a<<3)+(a<<1)+(ch^48);
    a*=d;
}
struct note{int ch[2],siz,tag,cnt,val,fa;}spl[N];
int rt,cnt,n,m;
void newnode(int &now,int fa,int val)
{
    spl[now=++cnt].val=val;
    spl[now].siz=spl[now].cnt=1;
    spl[now].fa=fa;
    spl[now].tag=0;
}
int ident(int x,int f){return spl[f].ch[1]==x;}///判断是否为右儿子
void connect(int x,int f,int s)
{
    spl[f].ch[s]=x;
    spl[x].fa=f;
}
void update(int now){spl[now].siz=spl[spl[now].ch[0]].siz+spl[spl[now].ch[1]].siz+1;}
void rotat(int x)
{
    int f=spl[x].fa,ff=spl[f].fa,k=ident(x,f);
    connect(spl[x].ch[k^1],f,k);
    connect(x,ff,ident(f,ff));
    connect(f,x,k^1);
    update(f),update(x);
}
void splaying(int x,int top)///把x转到top的儿子
{
    if(!top) rt=x;
    while(spl[x].fa!=top)
    {
        int f=spl[x].fa,ff=spl[f].fa;
        if(ff!=top) ident(f,ff)^ident(x,f)?rotat(x):rotat(f);
        rotat(x);
    }
}
void ins(int val,int &now=rt,int fa=0)
{
    if(!now) newnode(now,fa,val),splaying(now,0);
    else if(spl[now].val>val) ins(val,spl[now].ch[0],now);
    else if(spl[now].val<val) ins(val,spl[now].ch[1],now);
    else spl[now].siz++,splaying(now,0);
}
inline void pushdown(int x)
{
    if(spl[x].tag)
    {
        spl[spl[x].ch[0]].tag^=1;
        spl[spl[x].ch[1]].tag^=1;
        spl[x].tag=0;
        swap(spl[x].ch[0],spl[x].ch[1]);
    }
}
int getv(int k)
{
    int v=rt;
    while(1)
    {
        pushdown(v);
        if(spl[spl[v].ch[0]].siz>=k)v=spl[v].ch[0];
        else if(spl[spl[v].ch[0]].siz+1==k) return v;
        else k-=spl[spl[v].ch[0]].siz+1,v=spl[v].ch[1];
    }
}
void rever(int l,int r)
{
    l=getv(l);r=getv(r+2);
    splaying(l,0),splaying(r,l);
    spl[spl[spl[rt].ch[1]].ch[0]].tag^=1;
}
void ldr(int now)
{
    pushdown(now);
    if(!now) return;
    ldr(spl[now].ch[0]);
    if(spl[now].val>1&&spl[now].val<n+2) printf("%d ",spl[now].val-1);
    ldr(spl[now].ch[1]);
}
int main()
{
    read(n),read(m);
    for(re int i=1;i<=n+2;i++) ins(i,rt);
    for(re int i=1,x,y;i<=m;i++) read(x),read(y),rever(x,y);
    ldr(rt);
    return 0;
}
原文地址:https://www.cnblogs.com/acm1ruoji/p/11943620.html