zoukankan      html  css  js  c++  java
  • bzoj3224 Tyvj 1728 普通平衡树

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3224

    【题解】

    写起来跟*一样,但是还是挺快调出来了。

    主要就是每个数可以有多个,我们可以用一个splay节点存多个数,然后find即可。

    注意的是每个操作过后基本都要splay一下保证复杂度。

    # include <stdio.h>
    # include <string.h>
    # include <iostream>
    # include <algorithm>
    // # include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    const int M = 1e5 + 10;
    const int mod = 1e9+7;
    const int inf = 2e9 + 10;
    
    # define RG register
    # define ST static
    
    struct Splay {
        int ch[M][2], fa[M]; int val[M], sz[M], rt, siz, s[M];
        inline void set() {
            siz = 2; rt = 1;
            ch[1][0] = ch[2][0] = ch[2][1] = fa[1] = 0, ch[1][1] = 2; fa[2] = 1;
            sz[1] = 2, sz[2] = 1; val[1] = -inf, val[2] = inf; s[1] = s[2] = 1;
        }
        inline void up(int x) {
            if(!x) return ;
            sz[x] = s[x] + sz[ch[x][0]] + sz[ch[x][1]];
        }
        inline void rotate(int x, int &rt) {
            int y = fa[x], z = fa[y], ls = ch[y][1] == x, rs = ls^1;
            if(rt == y) rt = x;
            else ch[z][ch[z][1] == y] = x;
            fa[ch[x][rs]] = y, fa[y] = x, fa[x] = z;
            ch[y][ls] = ch[x][rs]; ch[x][rs] = y;
            up(y); up(x);
        }
        inline void splay(int x, int &rt) {
            while(x != rt) {
                int y = fa[x], z = fa[y];
                if(y != rt) {
                    if((ch[z][0] == y) ^ (ch[y][0] == x)) rotate(x, rt);
                    else rotate(y, rt);
                }
                rotate(x, rt);
            }
        }
        inline void ins(int &x, int lst, int p) {
            if(!x) {
                x = ++siz; fa[x] = lst; ch[x][0] = ch[x][1] = 0; sz[x] = 1;
                val[x] = p; s[x] = 1;
                return;
            }
            if(p == val[x]) {
                s[x] ++; sz[x] ++;
                return ;
            }
            if(p < val[x]) ins(ch[x][0], x, p);
            else ins(ch[x][1], x, p);
            up(x);
        }
        inline void INS(int p) {
            ins(rt, 0, p);
            splay(siz, rt);
        }
        
        inline int find(int x, int p) {
            if(!x) return inf;
            if(val[x] == p) return x;
            if(p < val[x]) return find(ch[x][0], p);
            else return find(ch[x][1], p);
        }
        
        
        inline int gpre(int x, int p) {
            if(!x) return inf;
            if(val[x] < p) {
                int y = gpre(ch[x][1], p);
                if(y != inf) return y;
                else return x;
            } else return gpre(ch[x][0], p);
        }
        inline int gsuf(int x, int p) {
            if(!x) return inf;
            if(val[x] > p) {
                int y = gsuf(ch[x][0], p);
                if(y != inf) return y;
                else return x;
            } else return gsuf(ch[x][1], p);
        }
        
        inline int pre(int x) {
            while(ch[x][1]) x = ch[x][1];
            return x;
        }
        inline int suf(int x) {
            while(ch[x][0]) x = ch[x][0];
            return x;
        }
        
        inline void DEL(int p) {
            int x = find(rt, p); 
            splay(x, rt);
            if(s[x] > 1) {
                --s[x]; up(x);
                return ;
            }
            int y = pre(ch[x][0]); splay(y, ch[x][0]);
            rt = y; fa[y] = 0; ch[y][1] = ch[x][1]; fa[ch[x][1]] = y;
            up(y); fa[x] = ch[x][0] = ch[x][1] = s[x] = sz[x] = 0;
        }
        
        inline void PRE(int p) {
            int x = find(rt, p);
            if(x == inf) {
                int y = gpre(rt, p);
                splay(y, rt); 
                printf("%d
    ", val[y]);
                return ;
            }
            splay(x, rt);
            int y = pre(ch[x][0]);
            printf("%d
    ", val[y]);
        }
        
        inline void SUF(int p) {
            int x = find(rt, p);
            if(x == inf) {
                int y = gsuf(rt, p);
                splay(y, rt);
                printf("%d
    ", val[y]);
                return ;
            }
            splay(x, rt);
            int y = suf(ch[x][1]);
            printf("%d
    ", val[y]);
        }
        
        inline void getrank(int p) {
            int x = find(rt, p); splay(x, rt);
            printf("%d
    ", sz[ch[x][0]]);
        }
        
        inline int findrk(int x, int p) {
            if(sz[ch[x][0]] + 1 <= p && p <= sz[ch[x][0]] + s[x]) return x;
            if(sz[ch[x][0]] + 1 > p) return findrk(ch[x][0], p);
            else return findrk(ch[x][1], p - s[x] - sz[ch[x][0]]);
        }
        
        inline void prank(int x) {
            int y = findrk(rt, x+1); splay(y, rt);
            printf("%d
    ", val[y]);
        }
    }T;
         
    
    int main() {
        int Q, op, x; cin >> Q; T.set();
        while(Q--) {
            scanf("%d%d", &op, &x);
            if(op == 1) T.INS(x);
            else if(op == 2) T.DEL(x);
            else if(op == 3) T.getrank(x);
            else if(op == 4) T.prank(x);
            else if(op == 5) T.PRE(x);
            else T.SUF(x);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    算法竞赛入门经典训练指南
    git保护--git分支创建
    解决多个iframe嵌套而造成的多个滚动条问题
    css如何让div元素铺满整个屏幕
    第一个用python3写的爬虫小例子
    用JS获取当前页面的URL以及截取其中的字段
    css处理超出文本截断问题的两种情况(多行或者单行)
    约数的个数
    成绩排序
    八进制
  • 原文地址:https://www.cnblogs.com/galaxies/p/bzoj3224.html
Copyright © 2011-2022 走看看