• Splay


    Splay - AcWing 950 - 郁闷的出纳员

    之前做过这道题目,当时是用权值线段树做的。本题还可以用splay做,splay用于维护一些区间问题。这是第一道凭个人记忆打出的splay模板,可以说对于splay有一个基本的理解了。

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N = 100010,INF = 1e9;
    
    int n,m,k;
    int root,idx;
    int delta,tot;
    char op[2];
    
    struct Node{
        int s[2],p,v;
        int size;
        void init(int _p,int _v){
            p = _p;
            v = _v;
        }
        
    }tr[N];
    
    
    
    inline int ws(int x){
        return tr[tr[x].p].s[1] == x;
    }
    
    void push_up(int x){
        tr[x].size = tr[tr[x].s[0]].size + tr[tr[x].s[1]].size + 1;
    }
    
    void rotate(int x){
        int y = tr[x].p;
        int z = tr[y].p;
        int k = ws(x);
        
        // modify z
        tr[z].s[ws(y)] = x;
        
        // modify y
        tr[y].p = x;
        tr[y].s[k] = tr[x].s[k^1];
        
        // modify m
        tr[tr[x].s[k^1]].p = y;
        
        // modify x
        tr[x].p = z;
        tr[x].s[k^1] = y;
        
        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(ws(x) ^ ws(y)){
                    rotate(x);
                }else{
                    rotate(y);
                }
            }
            rotate(x);
        }
        
        if(k == 0) root = x;
    }
    
    int 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(p,v);
        splay(u,0);
        return u;
    }
    
    int get_k(int k){
        int u = root;
        while(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;
    }
    
    
    // find the max one that leq than v
    int get_v(int v){
        int res = -1;
        int u = root;
        while(u){
            if(tr[u].v >= v){
                res = u;
                u = tr[u].s[0];
            }else{
                u = tr[u].s[1];
            }
        }
        return res;
    }
    
    
    int main(){
        scanf("%d%d",&n,&m);
        
        int L = insert(-INF), R = insert(INF);
        
        while(n--){
            scanf("%s%d",op,&k);
            
            if(*op == 'I'){
                if(k >= m){
                    ++tot;
                    insert(k-delta);
                }
            }else if(*op == 'A'){
                delta += k;
            }else if(*op == 'S'){
                delta -= k;
                // delete all less than m - delta
                R = get_v(m - delta);
                // [L,R]
                splay(R,0);
                splay(L,R);
                tr[L].s[1] = 0;
                push_up(L);
                push_up(R);
            }else{
                if(tr[root].size - 2 < k){
                    puts("-1");
                }else{
                    // tr[root].size - k
                    int test = get_k(tr[root].size - k);
                    printf("%d
    ",tr[test].v + delta);
                }
            }
        }
        
        printf("%d
    ",tot-(tr[root].size-2));
        return 0;
    }
    
    ---- suffer now and live the rest of your life as a champion ----
  • 相关阅读:
    Kafka 核心 API ==> AdminClient
    Kafka ==> 简介
    设计模式之 ==> 代理设计模式
    设计模式之 ==> 工厂设计模式
    设计模式之 ==> 模板设计模式
    设计模式之 ==> 单例模式
    Linux目录【持续更新中】
    Python 目录【持续更新中】
    kafka-eagle部署
    ES集群部署
  • 原文地址:https://www.cnblogs.com/popodynasty/p/14401085.html
Copyright © 2020-2023  润新知