splay树模板

对应模板题
照着巨佬博客的代码打的https://blog.csdn.net/Clove_unique/article/details/50630280

#include<map>
#include<set>
#include<cmath>
#include<stack>
#include<queue>
#include<cstdio>
#include<string>
#include<vector>
#include<cstring>
#include<iomanip>
#include<sstream>
#include<iostream>
#include<algorithm>
#define INF 0x3f3f3f3f
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define next _next
#define insert _insert
#define size _size
//#define ll __int64
//#define int ll
typedef  long long ll;
typedef unsigned long long ull;
const int MAXN=1e6+10;
const int MOD=1e9+7;
const double eps=1e-6;
const double finf=1e10;
using namespace std;
template<class T>inline void read(T &res)
{
    char c;T flag=1;
    while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
    while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
}
//-------------------------------------------//
int fa[MAXN],ch[MAXN][2],size[MAXN],key[MAXN],cnt[MAXN],root,sz;
inline void clear(int x)
{
    ch[x][0]=ch[x][1]=fa[x]=size[x]=key[x]=cnt[x]=0;
}
inline int check(int x)
{
    return ch[fa[x]][1]==x;
}
inline void updata(int x)
{
    if(x)
    {
        size[x]=cnt[x];
        if(ch[x][0])size[x]+=size[ch[x][0]];
        if(ch[x][1])size[x]+=size[ch[x][1]];
    }
}
inline void rotate(int x)
{
    int old=fa[x],oldf=fa[fa[x]],which=check(x);
    ch[old][which]=ch[x][which^1];fa[ch[x][which^1]]=old;
    ch[x][which^1]=old;fa[old]=x;
    fa[x]=oldf;
    if(oldf)ch[oldf][ch[oldf][1]==old]=x;
    updata(old);updata(x);
}
inline void splay(int x)
{
    for(int f;f=fa[x];rotate(x))
        if(fa[f])rotate((check(x)==check(f))?f:x);
    root=x;
}
inline void insert(int x)
{
    if(!root)
    {
        sz++;ch[sz][0]=ch[sz][1]=fa[sz]=0;key[sz]=x;
        cnt[sz]=size[sz]=1;root=sz;return;
    }
    int cur=root,father=0;
    while(1)
    {
        if(key[cur]==x)
        {
            cnt[cur]++;updata(cur);updata(father);
            splay(cur);break;
        }
        father=cur;
        cur=ch[cur][key[cur]<x];
        if(!cur)
        {
            sz++;
            ch[sz][0]=ch[sz][1]=0;
            fa[sz]=father;
            size[sz]=cnt[sz]=1;
            ch[father][key[father]<x]=sz;
            key[sz]=x;
            updata(father);
            splay(sz);break;
        }
    }
}
inline int find_val(int x)
{
    int res=0,cur=root;
    while(1)
    {
        if(x<key[cur])cur=ch[cur][0];
        else
        {
            res+=(ch[cur][0]?size[ch[cur][0]]:0);
            if(x==key[cur]){splay(cur);return res+1;}
            res+=cnt[cur];
            cur=ch[cur][1];
        }
    }
}
inline int find_k(int k)
{
    int cur=root;
    while(1)
    {
        if(ch[cur][0]&&k<=size[ch[cur][0]])cur=ch[cur][0];
        else
        {
            int temp=(ch[cur][0]?size[ch[cur][0]]:0)+cnt[cur];
            if(k<=temp)return key[cur];
            k-=temp; cur=ch[cur][1];
        }
    }
}
inline int pre()
{
    int cur=ch[root][0];
    while (ch[cur][1]) cur=ch[cur][1];
    return cur;
}
inline int next()
{
    int cur=ch[root][1];
    while (ch[cur][0]) cur=ch[cur][0];
    return cur;
}
inline void del(int x)
{
    find_val(x);
    if(cnt[root]>1){cnt[root]--; updata(root); return;}
    if(!ch[root][0]&&!ch[root][1]){clear(root); root=0; return;}
    if(!ch[root][0]){int oldrt=root; root=ch[root][1]; fa[root]=0; clear(oldrt); return;}
    else if(!ch[root][1]){int oldrt=root; root=ch[root][0]; fa[root]=0; clear(oldrt); return;}
    int newrt=pre(),oldrt=root;
    splay(newrt);
    fa[ch[oldrt][1]]=root;
    ch[root][1]=ch[oldrt][1];
    clear(oldrt);
    updata(root);
}
int main()
{
    int n,op,x;
    scanf("%d",&n);
    while(n--)
    {
        scanf("%d%d",&op,&x);
        switch(op)
        {
            case 1:insert(x); break;
            case 2:del(x); break;
            case 3:printf("%d\n",find_val(x)); break;
            case 4:printf("%d\n",find_k(x)); break;
            case 5:insert(x); printf("%d\n",key[pre()]);del(x);break;
            case 6:insert(x); printf("%d\n",key[next()]);del(x);break;
        }
    }
    return 0;
}

splay’s应用:区间翻转
文艺平衡树

#include<map>
#include<set>
#include<cmath>
#include<stack>
#include<queue>
#include<cstdio>
#include<string>
#include<vector>
#include<cstring>
#include<iomanip>
#include<sstream>
#include<iostream>
#include<algorithm>
#define INF 0x3f3f3f3f
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define next _next
#define insert _insert
#define size _size
//#define ll __int64
//#define int ll
typedef  long long ll;
typedef unsigned long long ull;
const int MAXN=1e6+10;
const int MOD=1e9+7;
const double eps=1e-6;
const double finf=1e10;
using namespace std;
template<class T>inline void read(T &res)
{
    char c;T flag=1;
    while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
    while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
}
//-------------------------------------------//
int fa[MAXN],ch[MAXN][2],size[MAXN],key[MAXN],lazy[MAXN],a[MAXN],root,sz;
inline void clear(int x)
{
    ch[x][0]=ch[x][1]=fa[x]=size[x]=key[x]=0;
}
inline int check(int x)
{
    return ch[fa[x]][1]==x;
}
inline void pushdown(int x)
{
    if(x&&lazy[x])
    {
        lazy[ch[x][0]]^=1;
        lazy[ch[x][1]]^=1;
        swap(ch[x][0],ch[x][1]);
        lazy[x]=0;
    }
}
inline void updata(int x)
{
    size[x]=size[ch[x][0]]+size[ch[x][1]]+1;
}
inline void rotate(int x)
{
    pushdown(fa[x]);pushdown(x);
    int old=fa[x],oldf=fa[fa[x]],which=check(x);
    ch[old][which]=ch[x][which^1]; fa[ch[x][which^1]]=old;
    ch[x][which^1]=old; fa[old]=x;
    fa[x]=oldf;
    if(oldf)ch[oldf][ch[oldf][1]==old]=x;
    updata(old);updata(x);
}
inline 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==0)root=x;
}
inline int build(int l,int r,int pre)
{
    if(l>r)return 0;
    int m=l+r>>1;
    int cur=++sz;
    key[cur]=a[m]; fa[cur]=pre; lazy[cur]=0;
    ch[cur][0]=build(l,m-1,cur);
    ch[cur][1]=build(m+1,r,cur);
    updata(cur);
    return cur;
}
inline int find_k(int k)
{
    int cur=root;
    while(1)
    {
        pushdown(cur);
        if(ch[cur][0]&&k<=size[ch[cur][0]])cur=ch[cur][0];
        else
        {
            k-=size[ch[cur][0]]+1;
            if(!k)return cur;
            cur=ch[cur][1];
        }
    }
}
inline void print(int cur)
{
    pushdown(cur);
    if(ch[cur][0])print(ch[cur][0]);
    if(key[cur]!=-INF&&key[cur]!=INF)printf("%d ",key[cur]);
    if(ch[cur][1])print(ch[cur][1]);
}
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;++i)a[i]=i;
    a[0]=-INF;a[n+1]=INF;
    root=build(0,n+1,0);
    while(m--)
    {
        int l,r;
        scanf("%d%d",&l,&r);
        int x=find_k(l);
        int y=find_k(r+2);
        splay(x,0);
        splay(y,x);
        lazy[ch[ch[root][1]][0]]^=1;
    }
    print(root);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值