zoukankan      html  css  js  c++  java
  • 左偏树学习笔记

    定义

    我不知道

    特殊作用

    可并

    从题目中得到的用处

    并查集优化

    左偏树主要有两个操作,一个是合并,一个是删除。

    对于合并,直接更新,可以看下面的代码。

    对于删除,也可以直接更新,注意把要删除的节点在并查集中保留,因为它可能是其他节点找爸爸路上的必经之点,可以看下面的代码。

    做题

    洛谷模板题目代码

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std; 
    
    const int N = 100000 + 5;
    struct In {
        const In operator, (int & a) const {
            a = 0;
            int f = 1;
            char k = getchar ();
            while (k > '9' || k < '0') {
                if (k == '-') {
                    f = -1;
                }
                k = getchar ();
            }
            while (k >= '0' && k <= '9') {
                a = a * 10 + k - '0';
                k = getchar ();
            }
            a *= f;
            return * this;
        }
    }in;
    struct Node {
        int val, id;
        bool operator < (Node x) {
            return val == x.val ? id < x.id : val < x.val;
        }
        bool operator > (Node x) {
            return val == x.val ? id > x.id : val > x.val;
        }
    }info[N];
    int n, m, fa[N], ch[N][2], dis[N];
    bool vis[N];
    
    inline int Find (int u) {
        return fa[u] == u ? u : fa[u] = Find (fa[u]);
    }
    
    inline int merge (int x, int y) {
        if (!x || !y) {
            return x + y;
        }
        if (info[x] > info[y]) {
            swap (x, y);
        }
        ch[x][1] = merge (ch[x][1], y);
        fa[ch[x][1]] = x;
        if (dis[ch[x][1]] > dis[ch[x][0]]) {
            swap (ch[x][1], ch[x][0]);
        }
        dis[x] = dis[ch[x][1]] + 1;
        return x;
    }
    
    inline void query (int u) {
        if (vis[u]) {
            printf ("-1
    ");
            return ;
        }
        u = Find (u);
        printf ("%d
    ", info[u].val);
        vis[u] = 1;
        ch[u][0] = merge (ch[u][0], ch[u][1]);
        fa[ch[u][0]] = ch[u][0];
        fa[u] = ch[u][0];
        ch[u][0] = ch[u][1] = 0;
    }
    
    inline void Merge (int u, int v) {
        if (vis[u] || vis[v]) {return ;}
        u = Find (u);
        v = Find (v);
        if (u == v) {return ;}
        merge (u, v);
    }
    
    int main () {
        in, n, m;
        for (int i = 1; i <= n; ++i) {
            in, info[i].val;
            info[i].id = i;
            fa[i] = i;
        }
        for (int i = 1; i <= m; ++i) {
            int opt, x, y;
            in, opt, x;
            if (opt == 1) {
                in, y;
                Merge (x, y);
            }
            else {
                query (x);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    职业的选择
    事务的隔离性理解
    浅谈CSS和JQuery实现鼠标悬浮图片放大效果
    jvm 类加载器
    jvm 类加载
    Spring 启动 Bean加载流程
    优雅的博客园客户端发布Forms版啦。
    Xamarin Forms中WebView的自适应高度
    2017回顾与2018目标
    优雅的博客园Android客户端
  • 原文地址:https://www.cnblogs.com/ChiTongZ/p/11241187.html
Copyright © 2011-2022 走看看