【总结】Splay和各种题目

Splay是平衡树的变种之一,希望大家不要掌握按照Anson的说法,能不写平衡树就不写

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<iostream>
using namespace std;
int n,m;
class BST{
private:
    struct node{
        int ch[2];
        int val,ff,size,cnt,mark;
    }t[500010];
    int root,tot;
    void pushup(int o){
        t[o].size=t[t[o].ch[0]].size+t[t[o].ch[1]].size+t[o].cnt;
    }
    void pushdown(int o){
        if(t[o].mark){
            t[t[o].ch[0]].mark^=1;
            t[t[o].ch[1]].mark^=1;
            t[o].mark=0;
            swap(t[o].ch[0],t[o].ch[1]);
        }
    }
    void rotate(int x){
        int y=t[x].ff,z=t[y].ff;
        int k=(t[y].ch[1]==x);
        t[z].ch[t[z].ch[1]==y]=x;
        t[x].ff=z;t[y].ch[k]=t[x].ch[k^1];
        t[t[x].ch[k^1]].ff=y;
        t[x].ch[k^1]=y;t[y].ff=x;
        pushup(x);pushup(y);
    }
public:
    void Splay(int x,int goal){
        while(t[x].ff!=goal){
            int y=t[x].ff,z=t[y].ff;
            if(z!=goal)
                (t[y].ch[0]==x)^(t[z].ch[0]==y)?rotate(x):rotate(y);
            rotate(x);
        }
        if(!goal)root=x;
    }
    void Insert(int x){
        int u=root,ff=0;
        while(u && t[u].val!=x){
            ff=u;
            u=t[u].ch[x>t[u].val];
        }
        if(u)t[u].cnt++;
        else{
            u=++tot;
            if(ff)t[ff].ch[x>t[ff].val]=u;
            t[u].ch[0]=t[u].ch[1]=0;
            t[u].ff=ff;t[u].size=t[u].cnt=1;
            t[u].val=x;
        }
        Splay(u,0);
    }
    int kth(int x){
        int u=root;
        while(9247){
            pushdown(u);
            int y=t[u].ch[0];
            if(x>t[y].size+t[u].cnt){
                x-=t[y].size+t[u].cnt;
                u=t[u].ch[1];
            }
            else
                if(t[y].size>=x)u=y;
                else return t[u].val;
        }
    }
    void Work(int l,int r){
        l=kth(l);
        r=kth(r+2);
        Splay(l,0);Splay(r,l);
        t[t[t[root].ch[1]].ch[0]].mark^=1;
    }
    void write(int u){
        pushdown(u);
        if(t[u].ch[0])write(t[u].ch[0]);
        if(t[u].val>1 && t[u].val<n+2)printf("%d ",t[u].val-1);
        if(t[u].ch[1])write(t[u].ch[1]);
    }
    void print(){
        write(root);
    }
}Splay;
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n+2;i++)Splay.Insert(i);
    while(m--){
        int l,r;scanf("%d%d",&l,&r);
        Splay.Work(l,r);
    }
    Splay.print();
    puts("");
    return 0;
}

以下是文艺平衡树

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<iostream>
using namespace std;
int n,m;
class BST{
private:
    struct node{
        int ch[2];
        int val,ff,size,cnt,mark;
    }t[500010];
    int root,tot;
    void pushup(int o){
        t[o].size=t[t[o].ch[0]].size+t[t[o].ch[1]].size+t[o].cnt;
    }
    void pushdown(int o){
        if(t[o].mark){
            t[t[o].ch[0]].mark^=1;
            t[t[o].ch[1]].mark^=1;
            t[o].mark=0;
            swap(t[o].ch[0],t[o].ch[1]);
        }
    }
    void rotate(int x){
        int y=t[x].ff,z=t[y].ff;
        int k=(t[y].ch[1]==x);
        t[z].ch[t[z].ch[1]==y]=x;
        t[x].ff=z;t[y].ch[k]=t[x].ch[k^1];
        t[t[x].ch[k^1]].ff=y;
        t[x].ch[k^1]=y;t[y].ff=x;
        pushup(x);pushup(y);
    }
public:
    void Splay(int x,int goal){
        while(t[x].ff!=goal){
            int y=t[x].ff,z=t[y].ff;
            if(z!=goal)
                (t[y].ch[0]==x)^(t[z].ch[0]==y)?rotate(x):rotate(y);
            rotate(x);
        }
        if(!goal)root=x;
    }
    void Insert(int x){
        int u=root,ff=0;
        while(u && t[u].val!=x){
            ff=u;
            u=t[u].ch[x>t[u].val];
        }
        if(u)t[u].cnt++;
        else{
            u=++tot;
            if(ff)t[ff].ch[x>t[ff].val]=u;
            t[u].ch[0]=t[u].ch[1]=0;
            t[u].ff=ff;t[u].size=t[u].cnt=1;
            t[u].val=x;
        }
        Splay(u,0);
    }
    int kth(int x){
        int u=root;
        while(9247){
            pushdown(u);
            int y=t[u].ch[0];
            if(x>t[y].size+t[u].cnt){
                x-=t[y].size+t[u].cnt;
                u=t[u].ch[1];
            }
            else
                if(t[y].size>=x)u=y;
                else return t[u].val;
        }
    }
    void Work(int l,int r){
        l=kth(l);
        r=kth(r+2);
        Splay(l,0);Splay(r,l);
        t[t[t[root].ch[1]].ch[0]].mark^=1;
    }
    void write(int u){
        pushdown(u);
        if(t[u].ch[0])write(t[u].ch[0]);
        if(t[u].val>1 && t[u].val<n+2)printf("%d ",t[u].val-1);
        if(t[u].ch[1])write(t[u].ch[1]);
    }
    void print(){
        write(root);
    }
}Splay;
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n+2;i++)Splay.Insert(i);
    while(m--){
        int l,r;scanf("%d%d",&l,&r);
        Splay.Work(l,r);
    }
    Splay.print();
    puts("");
    return 0;
}

转载于:https://www.cnblogs.com/cjgjh/p/9853070.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值