zoukankan      html  css  js  c++  java
  • Splay入门

    伸展树-Splay

    对于本题的区间flip操作,线段树难以实现;用splay来做非常合适。

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N = 1e5+50;
    
    int n,m;
    struct Node{
        int s[2],p,v;
        int size,flag;
        
        void init(int _v,int _p){
            v = _v;
            p = _p;
            size = 1;
        }
    }tr[N];
    
    int root,idx;
    
    void push_up(int x){
        tr[x].size = tr[tr[x].s[0]].size + tr[tr[x].s[1]].size + 1;
        
    }
    
    void push_down(int x){
        if(tr[x].flag){
            swap(tr[x].s[0],tr[x].s[1]);
            tr[tr[x].s[0]].flag ^= 1;
            tr[tr[x].s[1]].flag ^= 1;
            tr[x].flag = 0;
        }
    }
    
    void rotate(int x){
        int y = tr[x].p;
        int z = tr[y].p;
        int k = tr[y].s[1] == x;
        tr[z].s[tr[z].s[1] == y] = x;
        tr[x].p = z;
        
        tr[y].s[k] = tr[x].s[k^1];
        tr[tr[x].s[k^1]].p = y;
        
        tr[x].s[k^1] = y;
        tr[y].p = x;
        
        push_up(y);
        push_up(x);
    }
    
    
    void splay(int x,int k){
        while(tr[x].p != k){
            int y = tr[x].p;
            int z = tr[y].p;
            if(z != k){
                if((tr[y].s[1] == x) ^ (tr[z].s[1] == y)){
                    rotate(x);
                }else{
                    rotate(y);
                }
            }
            rotate(x);
        }
        if(!k) root = x;
    }
    
    void insert(int v){
        int u = root;
        int p = 0;
        while(u){
            p = u;
            u = tr[u].s[v > tr[u].v];
        }
        u = ++idx;
        if(p) tr[p].s[v > tr[p].v] = u;
        tr[u].init(v,p);
        splay(u,0);
    }
    
    
    int get_k(int k){
        int u = root;
        while(1){
            push_down(u);
            if(tr[tr[u].s[0]].size >= k){
                u = tr[u].s[0];
            }else if(tr[tr[u].s[0]].size + 1 == k){
                return u;
            }else{
                k -= tr[tr[u].s[0]].size + 1;
                u = tr[u].s[1];
            }
         }
        return -1;
    }
    
    void output(int u){
        push_down(u);
        if(tr[u].s[0])output(tr[u].s[0]);
        if(tr[u].v >= 1 && tr[u].v <= n) printf("%d ",tr[u].v); // 不是哨兵就输出
        if(tr[u].s[1])output(tr[u].s[1]);
    }
    
    int main(){
        
        scanf("%d%d",&n,&m);
        for(int i = 0; i <= n+1; ++i){
            insert(i);
        }
        
        while(m--){
            int l,r;
            scanf("%d%d",&l,&r);
            l = get_k(l);
            r = get_k(r+2);
            splay(l,0);
            splay(r,l);
            tr[tr[r].s[0]].flag = 1;
        }
        
        output(root);
        return 0;
    }
    
    
    ---- suffer now and live the rest of your life as a champion ----
  • 相关阅读:
    DB2创建序列
    hibernate注解影射表
    自定义异常类一
    【JVM】java方法区
    【JVM】java棧
    (2)java堆内存
    (1)java虚拟机概念和结构图
    枚举应用五
    设计模式之命令模式学习理解
    eclipse中javadoc给项目生成api文档
  • 原文地址:https://www.cnblogs.com/popodynasty/p/14352920.html
Copyright © 2011-2022 走看看