• 左偏树


    左偏树能干什么?

    合并堆。

    解决:BZOJ1445罗马游戏APIO2012-dispatching这样的题目

    左偏树是什么?

    可并堆的一种实现。

    可并堆又是什么?   可并堆(Mergeable Heap)是一种抽象数据类型,它除了支持优先队列的三个基本操作(Insert, Minimum, Delete-Min),还支持一个额外的操作——合并操作。

    那么——左偏树的定义:

     

     

                from黄源河《左偏树的特点及其应用》

     

    左偏树合并的过程:

           贴一个超级无敌好的解释

    补一张完整的图:

     还是来自黄前辈的文章

     

    左偏树要怎么写

    板子(罗马游戏 )

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 1000050;
    int val[N], l[N], r[N], d[N], fa[N];
    int x, y, n, m;
    char ord;
    // 合并以 x, y为根的堆,返回合并后的堆顶
    int merge(int x, int y) 
    {
        if(!x||!y) return x|y;
    // 键值小的作为堆顶
        if (val[x] > val[y])    swap(x, y);
        r[x] = merge(r[x], y);
    // 维护左偏性质
        if (d[r[x]] > d[l[x]])
            swap(l[x], r[x]);
    // 重新计算距离
        d[x] = d[r[x]] + 1;
        return x;
    }
    
    int find(int x) 
    {
      if(fa[x] == x) return x;
      else return fa[x] = find(fa[x]);
     }
    
    int main() 
    {
        scanf("%d", &n);
        for (int i = 1; i <= n; i++) {
            scanf("%d", &val[i]);
            fa[i] = i;
        }
    
        scanf("%d", &m);
        for (int i = 1; i <= m; i++) {
            cin >> ord;
            if (ord == 'M') {
                scanf("%d%d", &x, &y);
                if (val[x] < 0 || val[y] < 0) continue;
                x = find(x), y = find(y);
                if (x != y) {
                    int t = merge(x, y);
                    fa[x] = fa[y] = t;
                }
            } 
            else {
                scanf("%d", &x);
                if (val[x] < 0) {
                    puts("0");
                    continue;
                }
                x = find(x);
                printf("%d
    ", val[x]);
                val[x] = -1;
                fa[x] = merge(l[x], r[x]);
                fa[fa[x]] = fa[x];
            }
        }
        return 0;
    }

     ———————————————未完待续—————————

    推荐下黄前辈的论文:https://wenku.baidu.com/view/515f76e90975f46527d3e1d5.html

  • 相关阅读:
    RabbitMQ学习之:(一)初识、概念及心得
    给Eclipse_Android添加智能提示功能
    C#异步编程之:(三)使用TaskScheduler.UnobservedTaskException
    类设计技巧
    初始化块
    子类构造器
    静态域与静态方法
    构造器中调用另一个构造器
    重载
    无参数的构造器
  • 原文地址:https://www.cnblogs.com/phemiku/p/11622449.html
Copyright © 2020-2023  润新知