ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

7.11 【左偏树】

2022-07-11 09:37:00  阅读:128  来源: 互联网

标签:7.11 rs int fa ls 左偏 节点 dis


\(\large\text{Date: 7.11}\)

左偏树(可并堆)

\(\large\to\text{Link}\leftarrow\)

原理
定义: 若一个节点有儿子是空的,那么这个节点就叫空节点。而一个节点的 \(dis\) 值代表从这个节点出发,只经过右儿子到达一个空节点最少需要走的边数。

左偏树 的意思是:对于一棵树上的每一个节点,其左儿子的 \(dis\) 值大于等于右儿子的 \(dis\) 值,所以这棵树“向左偏”。

若以 \(u,v\) 为根的两个堆需要合并,由于已经维护好了左偏性质,所以只需要将 \(v\) 合并到 \(u\) 最右边的空节点,然后再递归维护左偏性质即可。

很显然,在最坏情况下,由于堆的性质,\(dis[1]\) 到达 \(\log n\),合并操作依然能够维持在 \(\cal O(\log n)\) ,是非常优秀的。

其实这棵树往哪偏都无所谓(

\(\rm Code\) 是最重要的:

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;

int n, m, heap[N];
int fa[N], ls[N], rs[N], dis[N];
bool del[N];

int find(int x) {
    return x == fa[x] ? x : fa[x] = find(fa[x]);
}

int Merge(int u, int v) {
    if(!u || !v) return u + v; // 为空就返回另一个节点的值
    if(heap[u] == heap[v] ? u > v : heap[u] > heap[v]) swap(u, v);
    rs[u] = Merge(rs[u], v);
    if(dis[ls[u]] < dis[rs[u]]) swap(ls[u], rs[u]);
    fa[ls[u]] = fa[rs[u]] = fa[u] = u;
    dis[u] = dis[rs[u]] + 1;
    return u;
}

void pop(int u) {
    del[u] = true;
    fa[ls[u]] = ls[u];
    fa[rs[u]] = rs[u];
    fa[u] = Merge(ls[u], rs[u]);
}

void init() {
    for(int i = 1; i <= n; i++) fa[i] = i;
}

signed main() {
#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
    freopen("Ans.txt", "w", stdout);
#endif
    dis[0] = -1;
    scanf("%d %d", &n, &m);
    init();
    for(int i = 1; i <= n; i++) scanf("%d", &heap[i]);
    for(int opt, x, y; m--; ) {
        scanf("%d", &opt);
        if(opt == 1) {
            scanf("%d %d", &x, &y);
            if(del[x] || del[y]) continue;
            x = find(x); y = find(y);
            if(x != y) fa[x] = fa[y] = Merge(x, y);
        }
        else {
            scanf("%d", &x);
            if(del[x]) { puts("-1"); continue; }
            x = find(x);
            printf("%d\n", heap[x]);
            pop(x);
        }
    }
    return 0;
}

这图挺好看

\(\rm Link\)

标签:7.11,rs,int,fa,ls,左偏,节点,dis
来源: https://www.cnblogs.com/Doge297778/p/16465370.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有