罗马游戏(左偏树)

Posted zcr-blog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了罗马游戏(左偏树)相关的知识,希望对你有一定的参考价值。

技术图片

 

左偏树模板题。

只不过这里要加上并查集的路径压缩(因为要找堆顶),不然复杂度是错的。

因为一个人被杀了,他就没了,为了证明他没了,所以要把他的val设成-1。

#include <iostream>
#include <cstdio>
using namespace std;
const int N = 1000010;
struct Leftist_Tree{
    int lson, rson, val, dist, fa;
}t[N];
int merge(int x, int y) {
    if (!x || !y) return x | y;
    if (t[x].val > t[y].val) {
        swap(x, y);
    }
    t[x].rson = merge(t[x].rson, y);
    if (t[t[x].rson].dist > t[t[x].lson].dist) {
        swap(t[x].lson, t[x].rson);
    }
    t[t[x].lson].fa = t[t[x].rson].fa = t[x].fa = x;
    t[x].dist = t[x].dist + 1;
    return x;
}
int get(int x) {
    return t[x].fa == x ? x : t[x].fa = get(t[x].fa);//路径压缩
}
void pop(int x) {
    t[x].val = -1;
    t[t[x].lson].fa = t[x].lson;
    t[t[x].rson].fa = t[x].rson;
    t[x].fa = merge(t[x].lson, t[x].rson);
}
int n, m, a[N];
int main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
        scanf("%d", &a[i]);
        t[i].fa = i;
        t[i].val = a[i];
    }
    scanf("%d", &m);
    while (m--) {
        char opt[5];
        int x, y;
        scanf("%s%d", opt + 1, &x);
        if (opt[1] == M) {
            scanf("%d", &y);
            if (t[x].val == -1 || t[y].val == -1) continue;
            if (get(x) == get(y)) continue; 
            t[get(x)].fa = t[get(y)].fa = merge(get(x), get(y));
        } else {
            if (t[x].val == -1) puts("0"); 
            else printf("%d
", t[get(x)].val), pop(get(x));
        }
    }
    return 0;
}

 

以上是关于罗马游戏(左偏树)的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ 1455 罗马游戏 左偏树

[bzoj1455]罗马游戏_左偏树_并查集

bzoj1455: 罗马游戏 左偏树

裸裸的左偏树BZOJ1455-罗马游戏

[BZOJ 1455]罗马游戏(左偏树+并查集)

BZOJ 1455 1455: 罗马游戏 (可并堆-左偏树+并查集)