• Splay 伸展树 bzoj3224 bzoj3223


    Splay 伸展树, 平衡树的一种实现方法

    splay的精髓在于 rotate函数, 这里不多作介绍, 以及有大牛把原理及实现方法解释的很清楚了,这里只贴一下自己实现的代码,代码参考  :史上最详尽的平衡树(splay)讲解与模板

    下面是我自己的代码:

    bzoj 3224 

    传送门:Tyvj 1728 普通平衡树

    #include "iostream"
    #include "iomanip"
    #include "string.h"
    #include "stack"
    #include "queue"
    #include "string"
    #include "vector"
    #include "set"
    #include "map"
    #include "algorithm"
    #include "stdio.h"
    #include "math.h"
    #pragma comment(linker, "/STACK:102400000,102400000")
    #define bug(x) cout<<x<<" "<<"UUUUU"<<endl;
    #define mem(a,x) memset(a,x,sizeof(a))
    #define step(x) fixed<< setprecision(x)<<
    #define mp(x,y) make_pair(x,y)
    #define pb(x) push_back(x)
    #define ll long long
    #define endl ("
    ")
    #define ft first
    #define sd second
    #define lrt (rt<<1)
    #define rrt (rt<<1|1)
    using namespace std;
    const ll mod=1e9+7;
    const ll INF = 1e18+1LL;
    const int inf = 1e9+1e8;
    const double PI=acos(-1.0);
    const int N=1e6+100;
    
    int fa[N], ch[N][2], siz[N], cnt[N], key[N];
    int sz, root;
    
    inline void update(int x){
        siz[x] = cnt[x];
        siz[x] += siz[ch[x][0]] + siz[ch[x][1]];
    }
    
    inline void Clear(int x){
        fa[x] = ch[x][0] = ch[x][1] = siz[x] = cnt[x] = key[x] = 0;
    }
    
    inline bool get(int x){
        return ch[fa[x]][1] == x;
    }
    
    void Rotate(int x){
        int old = fa[x], oldf = fa[old], which = get(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;
        update(old), update(x);
    }
    
    void splay(int x){
        while(fa[x]){
            if(get(x) == get(fa[x]) && fa[fa[x]]) Rotate(fa[x]);
            Rotate(x);//cout<<" x 
    ";
        }
        root = x;
    }
    
    void Insert(int x){
        if(root == 0){
            sz++, root = cnt[sz] = siz[sz] = 1, key[sz] = x;
            return;
        }
        int now = root, f = 0;
        while(1){
            if(key[now] == x){
                cnt[now]++, update(now), update(f), splay(now); break;
            }
            f = now, now = ch[now][x>key[now]];
            if(now == 0){
                sz++, cnt[sz] = 1, key[sz] = x, siz[sz] = 1, fa[sz] = f, ch[f][x>key[f]] = sz;
                update(f), splay(sz); break;
            }
        }
    }
    
    inline int finds(int v){
        int now = root, ret=0;
        while(1){
            if(v == key[now]){
                ret += siz[ch[now][0]];
                splay(now);
                return ret+1;
            }
            if(v < key[now]) now = ch[now][0];
            else if(v > key[now]) ret += cnt[now] + siz[ch[now][0]], now = ch[now][1];
        }
    }
    
    inline int findx(int x){
        int now = root;
        while(1){
            int t = siz[ch[now][0]] + cnt[now];
            if(x <= siz[ch[now][0]]) now = ch[now][0];
            else if(x <= t) return key[now];
            else x -= t, now = ch[now][1];
        }
    }
    
    inline int pre(){
        int now = ch[root][0];
        while(ch[now][1]) now = ch[now][1];
        return now;
    }
    
    inline int nex(){
        int now = ch[root][1];//cout<<key[ch[now][1]]<<" u 
    ";
        while(ch[now][0]) now = ch[now][0];
        return now;
    }
    
    inline void del(int x){//cout<<key[root]<<endl;
        finds(x);
        if(cnt[root]>1){
            cnt[root]--, update(root); return;
        }
        if(ch[root][0]==0 && ch[root][1]==0){
            Clear(root), root =0; return;
        }
        if(ch[root][0] && ch[root][1]){
            int p = pre(), old = root;
            splay(p);
            fa[ch[old][1]] = root;
            ch[root][1] = ch[old][1];
            Clear(old), update(root);
            return;
        }
        int old = root;
        root = ch[root][ch[root][0]==0], fa[root] = 0, Clear(old);
    }
    int main(){
        int n, opt, x;
        scanf("%d", &n);
        for (int i=1; i<=n; ++i){
            scanf("%d %d",&opt, &x);
            switch(opt){
                case 1: Insert(x); break;
                case 2: del(x); break;
                case 3: printf("%d
    ",finds(x)); break;
                case 4: printf("%d
    ",findx(x)); break;
                case 5: Insert(x); printf("%d
    ", key[pre()]); del(x); break;
                case 6: Insert(x); printf("%d
    ", key[nex()]); del(x); break;
            }
        }
        return 0;
    }

     bzoj 3223

    传送门:HYSBZ - 3223 

    #include "iostream"
    #include "iomanip"
    #include "string.h"
    #include "stack"
    #include "queue"
    #include "string"
    #include "vector"
    #include "set"
    #include "map"
    #include "algorithm"
    #include "stdio.h"
    #include "math.h"
    #pragma comment(linker, "/STACK:102400000,102400000")
    #define bug(x) cout<<x<<" "<<"UUUUU"<<endl;
    #define mem(a,x) memset(a,x,sizeof(a))
    #define step(x) fixed<< setprecision(x)<<
    #define mp(x,y) make_pair(x,y)
    #define pb(x) push_back(x)
    #define ll long long
    #define endl ("
    ")
    #define ft first
    #define sd second
    #define lrt (rt<<1)
    #define rrt (rt<<1|1)
    using namespace std;
    const ll mod=1e9+7;
    const ll INF = 1e18+1LL;
    const int inf = 1e9+1e8;
    const double PI=acos(-1.0);
    const int N=1e5+100;
    
    int siz[N], ch[N][2], cnt[N], key[N], fa[N], lazy[N];
    int root, sz, n, m;
    
    void Clear(int x){
        siz[x] = ch[x][0] = ch[x][1] = cnt[x] = key[x] = fa[x] = 0;
    }
    
    void update(int x){
        siz[x] = cnt[x];
        siz[x] += siz[ch[x][0]] + siz[ch[x][1]];
    }
    
    bool get(int x){
        return ch[fa[x]][1] == x;
    }
    
    void pushdown(int x){
        if(lazy[x]){
            swap(ch[x][0], ch[x][1]);
            lazy[ch[x][0]] ^= 1, lazy[ch[x][1]] ^= 1;
        }
        lazy[x] = 0;
    }
    void Rotate(int x){
        pushdown(fa[x]), pushdown(x);
        int fx = fa[x], ffx = fa[fx], which = get(x);
        ch[fx][which] = ch[x][which^1], fa[ch[x][which^1]] = fx;
        ch[x][which^1] = fx, fa[fx] = x;
        fa[x] = ffx;
        if(ffx) ch[ffx][ch[ffx][1]==fx] = x;
        update(fx), update(x);
    }
    
    void splay(int x, int goal){
        while(fa[x] != goal){
            if(get(x)==get(fa[x]) && fa[fa[x]] && fa[fa[x]]!=goal)
                Rotate(fa[x]);
            Rotate(x);
        }
        if(goal==0) root = x;
    }
    
    int findx(int x){
        int now = root;
        pushdown(now);
        while(1){
            int t = cnt[now] + siz[ch[now][0]];
            if(x <= siz[ch[now][0]]) now = ch[now][0];
            else if(x <= t) return now;
            else x -= t, now = ch[now][1];
            pushdown(now);
        }
    }
    
    void change(int l, int r){
        int fl = findx(l),  fr = findx(r+2); //cout<<key[fl]<<"qq
    ";
        splay(fl, 0), splay(fr, root);
        lazy[ch[ch[root][1]][0]] ^= 1;
    }
    
    void Insert(int x){
        if(root == 0){
            sz++, root = cnt[sz] = siz[sz] = 1, key[sz] = x;
            return;
        }
        int now = root, f = 0;
        while(1){
            if(key[now] == x){
                cnt[now]++, update(now), update(f), splay(now, 0); break;
            }
            f = now, now = ch[now][x>key[now]];
            if(now == 0){
                sz++, cnt[sz] = 1, key[sz] = x, siz[sz] = 1, fa[sz] = f, ch[f][x>key[f]] = sz;
                update(f), splay(sz, 0); break;
            }
        }
    }
    
    int build(int l, int r, int f){//cout<<" UU
    ";
        if(l > r) return 0;
        int mid = l+r>>1, u = ++sz;
        if(l == r){
            cnt[u] = 1, siz[u] = 1, fa[u] = f, key[u] = l-1;
            return u;
        }
        ch[u][0] = build(l, mid-1, u);
        ch[u][1] = build(mid+1, r, u);
        cnt[u] = 1, siz[u] = 1, fa[u] = f, key[u] = mid-1;
        update(u);
        return u;
    }
    
    void dfs(int x){
        if(!x) return;
        pushdown(x);
        dfs(ch[x][0]);
        if(key[x]>=1 && key[x]<=n) printf("%d ", key[x]);
        dfs(ch[x][1]);
    }
    
    int main(){
        scanf("%d %d", &n, &m);
        //for(int i=0; i<=n+1; ++i) Insert(i);
        root = build(1, n+2, 0);
        while(m--){
            int l, r;
            scanf("%d %d", &l, &r);
            change(l, r);
        }
        dfs(root);
        return 0;
    }
  • 相关阅读:
    Android PopupWindow 弹窗背景半透明,设置最大高度
    Android性能优化之:ViewStub
    EventBus使用详解(一)——初步使用EventBus
    Android开发中,那些让你相见恨晚的方法、类或接口
    android 提高进程优先级 拍照永不崩溃(闪退)
    Android框架 加载图片 库 Picasso 的使用简介
    vc 取windows系统信息 版本 cpu信息 内存信息 ie版本信息 office版本
    VC 三点 划 曲线
    VC 类泡泡龙游戏算法
    vc 判断哪个按键 被按下 消息 按键 状态
  • 原文地址:https://www.cnblogs.com/max88888888/p/8490174.html
Copyright © 2020-2023  润新知