• 洛谷 [P3224] 永无乡


    Treap 的合并

    首先感谢 @Capella 的DeBug
    其次,这是由一个 & 号引发的血案
    注意对于所有修改操作都要 &
    Treap的合并, 启发式合并,对于每一个节点都 insert ,注意垃圾回收

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #define ll long long
    #define inf 0x3f3f3f3f
    using namespace std;
    const int MAXN = 500005;
    int init() {
        int rv = 0, fh = 1;
        char c = getchar();
        while(c < '0' || c > '9') {
            if(c == '-') fh = -1;
            c = getchar();
        }
        while(c >= '0' && c <= '9') {
            rv = (rv<<1) + (rv<<3) + c - '0';
            c = getchar();
        }
        return fh * rv;
    }
    int pool[MAXN], top, n, m, id[MAXN], q;
    struct UFS {
        int fa[MAXN];
        void unit() {
            for(int i = 1; i <= n; i++) fa[i] = i;
        }
        int find(int x) {
            if(x != fa[x]) return fa[x] = find(fa[x]);
            return fa[x];
        }
    }ufs;
    struct node{
        int val, dat, num, size, l, r;
    }a[MAXN];
    struct Treap{
        int New(int x, int num) {
            int ret = pool[++top];
            a[ret].val = x;
            a[ret].num = num;
            a[ret].dat = rand();
            a[ret].size = 1;
            a[ret].l = a[ret].r = 0;
            return ret;
        }
        void del(int &rt) {pool[top--] = rt;rt = 0;}
        void PushUp(int rt) {
            a[rt].size = a[a[rt].l].size + a[a[rt].r].size + 1; 
        }
        void zig(int &rt) {
            int nxt = a[rt].l;
            a[rt].l = a[nxt].r; a[nxt].r = rt; rt = nxt;
            PushUp(a[rt].r);
            PushUp(rt);
        }
        void zag(int &rt) {
            int nxt = a[rt].r;
            a[rt].r = a[nxt].l; a[nxt].l = rt; rt = nxt;
            PushUp(a[rt].l);
            PushUp(rt);
        }
        void Insert(int &rt, int x, int num) {
            if(!rt) {
                rt = New(x, num);
                return;
            }
            if(x < a[rt].val) {
                Insert(a[rt].l, x, num);
                if(a[a[rt].l].dat > a[rt].dat) zig(rt);
            }else {
                Insert(a[rt].r, x, num);
                if(a[a[rt].r].dat > a[rt].dat) zag(rt);
            }
            PushUp(rt);
        }
        int GetNum(int rt, int x) {
            if(!rt) return -1;
            if(a[a[rt].l].size >= x) return GetNum(a[rt].l, x);
            if(a[a[rt].l].size + 1 >=x) return a[rt].num;
            return GetNum(a[rt].r,x - 1 - a[a[rt].l].size);
        }
        void merge(int /*x*/&x, int &y) {
            if(!y) return;
            if(a[y].l) 
            merge(x, a[y].l);
            if(a[y].r) 
            merge(x, a[y].r);
            Insert(x, a[y].val, a[y].num);del(y);
        }
    }bst;
    void merge(int u, int v) {
        int r1 = ufs.find(u), r2 = ufs.find(v);
        if(r1 != r2) {
            if(a[id[r1]].size < a[id[r2]].size) {
                ufs.fa[r1] = r2;
                bst.merge(id[r2], id[r1]);
            }else {
                ufs.fa[r2] = r1;
                bst.merge(id[r1], id[r2]);
            }
        }
    }
    int main() {
        n = init(); m = init();
        ufs.unit();
        for(int i = 0; i < MAXN; i++) pool[i] = i;
        for(int i = 1; i <= n; i++) {
            int t = init();
            id[i] = bst.New(t, i);
        }
        for(int i = 1; i <= m; i++) {
            int u = init(), v = init();
            if(!u || !v) continue;
            merge(u, v);
        }
        q = init();
        for(int i = 1; i <= q; i++) {
            char t;
            scanf(" %c ", &t);
            if(t == 'Q') {
                int x = init(), k = init();
                printf("%d
    ", bst.GetNum(id[ufs.find(x)], k));
            }else {
                int u = init(), v = init();
                if(!u || !v) continue;
                merge(u, v);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    CSP2019 Day2T3 树的重心
    51nod1835 完全图
    [HNOI2015]亚瑟王
    [六省联考2017]分手是祝愿
    洛谷P4550 收集邮票
    06_手工负载分担(数通华为)
    05_配置交换机SSH服务(数通华为)
    04_配置交换机Telnet服务(数通华为)
    03_vlan & access & trunk 口(数通华为)
    02_搭建HTTP客户端与服务器(数通华为)
  • 原文地址:https://www.cnblogs.com/Mr-WolframsMgcBox/p/8604246.html
Copyright © 2020-2023  润新知