Splay

· · 个人记录

普通平衡树:

#include<bits/stdc++.h>
using namespace std;
const int maxn=100010;
const int inf=0x3f3f3f3f;
int n,tot,root;
int ch[maxn][2],fa[maxn],val[maxn],cnt[maxn],size[maxn];
inline int read()
{
    char c=getchar();int res=0,f=1;
    while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();}   
    while(c>='0'&&c<='9') res=res*10+c-'0',c=getchar();
    return res*f;
}
bool check(int p){return ch[fa[p]][1]==p;}
void up(int p){size[p]=size[ch[p][0]]+size[ch[p][1]]+cnt[p];}
void rotate(int p)
{
    int x=fa[p],y=fa[x],k=check(p),z=ch[p][k^1];//x->father,y->grandfather
    ch[x][k]=z,fa[z]=x;
    ch[y][check(x)]=p,fa[p]=y;
    ch[p][k^1]=x,fa[x]=p;
    up(x),up(p);
}
void splay(int p,int goal)
{
    while(fa[p]!=goal)
    {
        int x=fa[p],y=fa[x];
        if(y!=goal)
        {
            if(check(p)==check(x)) rotate(x);
            else rotate(p);
        }
        rotate(p);
    }
    if(!goal) root=p;
}
void insert(int k)
{
    int p=root,last=0;
    while(p&&val[p]!=k) last=p,p=ch[p][val[p]<k];
    if(p) cnt[p]++;
    else 
    {
        p=++tot;
        if(last) ch[last][val[last]<k]=p;
        ch[p][0]=ch[p][1]=0;fa[p]=last;val[p]=k;cnt[p]=size[p]=1;
    }
    splay(p,0);
}
void find(int k)//p(val=k)->root
{
    int p=root;
    while(ch[p][val[p]<k]&&val[p]!=k)p=ch[p][val[p]<k];
    splay(p,0);
}

int kth(int k)
{
    //puts("11");
    int p=root;
    while(23333)
    {
        if(ch[p][0]&&k<=size[ch[p][0]]) p=ch[p][0];
        else if(k>size[ch[p][0]]+cnt[p]) k-=size[ch[p][0]]+cnt[p],p=ch[p][1];
        else return p;
    }
}
int pre(int k)
{
    find(k);
    if(val[root]<k) return root;
    int p=ch[root][0];
    while(ch[p][1]) p=ch[p][1];
    return p;
}
int nxt(int k)
{
    find(k);
    if(val[root]>k) return root;
    int p=ch[root][1];
    while(ch[p][0]) p=ch[p][0];
    return p;
}
void delet(int k)
{
    int last=pre(k),next=nxt(k);
    splay(last,0),splay(next,root);//ch[next][0] only have p(val=k) 
    int del=ch[next][0];
    if(cnt[del]>1) cnt[del]--,splay(del,0);
    else ch[next][0]=0,up(next),up(root);
}
int main()
{
    n=read();
    insert(inf),insert(-inf);
    for(int i=1;i<=n;i++)
    {
        int op=read(),k=read();
        if(op==1)insert(k);
        if(op==2)delet(k);
        if(op==3)find(k),printf("%d\n",size[ch[root][0]]);
        if(op==4)printf("%d\n",val[kth(k+1)]);//insert->inf/-inf
        if(op==5)printf("%d\n",val[pre(k)]);
        if(op==6)printf("%d\n",val[nxt(k)]);
    }
    return 0;
}

文艺平衡树:

#include<bits/stdc++.h>
using namespace std;
const int maxn=100010;
int n,m,tot,root;
int ch[maxn][2],fa[maxn],val[maxn],cnt[maxn],size[maxn];
bool rev[maxn];
inline int read()
{
    char c=getchar();int res=0,f=1;
    while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();}   
    while(c>='0'&&c<='9') res=res*10+c-'0',c=getchar();
    return res*f;
}
bool check(int p){return ch[fa[p]][1]==p;}
void up(int p){size[p]=size[ch[p][0]]+size[ch[p][1]]+cnt[p];}
inline void down(int p)
{
    if(!rev[p]) return;
    swap(ch[p][0],ch[p][1]);
    rev[ch[p][0]]^=1;rev[ch[p][1]]^=1;rev[p]=0;
}
inline void rotate(int p)
{
    int x=fa[p],y=fa[x],k=check(p),z=ch[p][k^1];
    ch[x][k]=z,fa[z]=x;
    ch[y][check(x)]=p,fa[p]=y;
    ch[p][k^1]=x,fa[x]=p;
    up(x),up(p);
}
inline void splay(int p,int goal)
{
    while(fa[p]!=goal)
    {
        int x=fa[p],y=fa[x];
        if(y!=goal) 
        {
            if(check(p)==check(x)) rotate(x);
            else rotate(p);
        }
        rotate(p);
    }
    if(!goal) root=p;
}
inline void insert(int k)
{
    int p=root,last=0;
    while(p&&val[p]!=k) last=p,p=ch[p][val[p]<k];
    if(p) cnt[p]++;
    else 
    {
        p=++tot;
        if(last) ch[last][val[last]<k]=p;
        ch[p][0]=ch[p][1]=0;fa[p]=last;val[p]=k;cnt[p]=size[p]=1;
    }
    splay(p,0);
}
inline int kth(int k)
{
    int p=root;
    while(2333)
    {
        down(p);
        if(ch[p][0]&&k<=size[ch[p][0]]) p=ch[p][0];
        else if(k>size[ch[p][0]]+cnt[p]) k-=size[ch[p][0]]+cnt[p],p=ch[p][1];
        else return p;
    }
}
inline void reverse(int l,int r)
{
    int x=kth(l),y=kth(r+2);//l->l-1,r->r+1
    splay(x,0);splay(y,x);
    rev[ch[y][0]]^=1;
}
void print(int p)
{
    down(p);
    if(ch[p][0]) print(ch[p][0]);
    if(val[p]&&val[p]<=n) printf("%d ",val[p]);
    if(ch[p][1]) print(ch[p][1]);
}
int main()
{
    n=read(),m=read();
    for(int i=0;i<=n+1;i++) insert(i);
    for(int i=1;i<=m;i++){int l=read(),r=read();reverse(l,r);}
    print(root);
    return 0;
}