• 文艺平衡树


    #include<bits/stdc++.h>
    #define MAXN 300005
    using namespace std;
    int n,m,a,b;
    struct Splay{
        int num[MAXN],ch[MAXN][2],sz[MAXN],f[MAXN],cnt[MAXN],rt,tot,tag[MAXN];
        int get(int x){
            return (x==ch[f[x]][1]);
        }
        int up(int x){
            sz[x] = cnt[x];
            if(ch[x][0])sz[x] = sz[x]+sz[ch[x][0]];
            if(ch[x][1])sz[x] = sz[x]+sz[ch[x][1]];
            return 0;
        }
        int down(int x){
            if(tag[x]){
            tag[x] = 0;
            swap(ch[x][0],ch[x][1]);
            if(ch[x][0])tag[ch[x][0]] = tag[ch[x][0]]^1;
            if(ch[x][1])tag[ch[x][1]] = tag[ch[x][1]]^1;
            
            }
        }
        int found(int x){
            int now=rt,ans=1;
            while(1){
                if(num[now]<=x){
                    ans =     ans+sz[ch[now][0]];
                    if(num[now]==x){
                    return ans;
                    }
                    ans = ans+cnt[now];
                    now = ch[now][1];
                }
                else{
                    now = ch[now][0];
                }
            }
        }
        int rote(int x){
            int y = f[x],z = f[y],k = get(x),p = get(y);
            down(y),down(x);
            if(y==0)return 0;
            if(z)ch[z][p] = x;
            if(ch[x][k^1])f[ch[x][k^1]] = y;
            ch[y][k] = ch[x][k^1];
            ch[x][k^1] = y;
            f[x] = z;
            f[y] = x;
            up(y);up(x);
            return 0;
        }
        int splay(int x){
            for(int y = f[x];(y = f[x]);rote(x)){
                rote((get(x)==get(y))?y:x);
            }
            rt = x;
            return 0;
        }
        int rank(int x){
            int now=rt,ans=1;
            while(1){
                if(num[now]<=x){
                    ans =     ans+sz[ch[now][0]];
                    if(num[now]==x){
                    splay(now);
                    return ans;
                    }
                    ans = ans+cnt[now];
                    now = ch[now][1];
                }
                else{
                    now = ch[now][0];
                }
            }
        }
        int pre(){//前继 比她小的最大 
            int now = ch[rt][0];
            while(ch[now][1])now = ch[now][1];
            return now;
        }
        int suc(){
            int now = ch[rt][1];
            while(ch[now][0])now = ch[now][0];
            return now;
        }
        int add(int x){
            int now = rt;
            while(1){
                down(now);
                if(num[now]==x){
                    cnt[now]++;
                    splay(now);
                    return 0;
                }
                int to = (num[now]<x);
                if(!ch[now][to]){
                    tot++;
                    ch[now][to] = tot;
                    num[tot] = x;
                    f[tot] = now;
                    cnt[tot] = 1;
                    sz[tot] = 1;
                    splay(tot);
                    return 0;
                }
                else now = ch[now][to];
            }
        }
        int kth(int x){
            int now =rt;
            while(1){
                down(now);
                if(sz[ch[now][0]]<x){
                    x = x-sz[ch[now][0]];
                    if(x<=cnt[now])return num[now];
                    x = x-cnt[now];
                    now = ch[now][1];
                }
                else{
                    now = ch[now][0];
                }
            }
        }
        int del(int x){
            rank(x);
            if(cnt[rt]>=2){
                cnt[rt]--;
                sz[rt]--;
                return 0;
            }
            else{
                if((!ch[rt][0])&&(!ch[rt][1])){
                    rt = 0;
                    return 0;
                }
                if(ch[rt][0]&&(!ch[rt][1])){
                    f[ch[rt][0]] = 0;
                    rt =ch[rt][0];
                    return 0;
                }
                if((!ch[rt][0])&&ch[rt][1]){
                    f[ch[rt][1]] = 0;
                    rt =ch[rt][1];
                    return 0;
                }
                else{
                    splay(pre());
                    ch[rt][1] = ch[ch[rt][1]][1];
                    f[ch[rt][1]] = rt;
                    up(rt);
                    return 0;
                }
            }
        }
        int splay2(int x){
            for(int y = f[x];(y = f[x])!=rt;rote(x)){
                if(f[y]!=rt)rote((get(x)==get(y))?y:x);
            }
            return 0;
        }
        int turn(int x,int g){
            int p=kth(x-1),k=kth(g+1);
            splay(p);
            splay2(k);
            tag[ch[ch[rt][1]][0]] = 1^tag[ch[ch[rt][1]][0]];
        }
        int print(int now){
            down(now);
            if(ch[now][0])print(ch[now][0]);
            if(num[now]>1&&num[now]<n+2)cout<<num[now]-1<<" ";
            if(ch[now][1])print(ch[now][1]);
        }
    }T;
    
    int main(){
        cin>>n>>m;
        for(int i=1;i<=n+2;i++)T.add(i);    
        for(int i=1;i<=m;i++){
            cin>>a>>b;
            T.turn(a+1,b+1);
            
        }
        T.print(T.rt);
    }
    View Code

    很好的模板题

  • 相关阅读:
    总结:工作 + 学习 (2019年)
    JVM 理解性学习(一)
    渗透神器cobalt strike在数字杀软环境下的使用
    普通路由器刷开源固件DD-WRT的简单过程
    云烟渗透题总结
    对thinkphp5.0框架的实例学习
    内网渗透 关于GPO
    简单尝试利用维控LeviStudioU的一栈缓冲区溢出漏洞
    试写foxit reader的ConvertToPDF功能的wrapper
    第05章下 加载内核
  • 原文地址:https://www.cnblogs.com/shatianming/p/12234458.html
Copyright © 2020-2023  润新知