码迷,mamicode.com
首页 > 其他好文 > 详细

罗马游戏(左偏树)

时间:2020-05-10 17:03:27      阅读:55      评论:0      收藏:0      [点我收藏+]

标签:技术   mic   oid   int   col   idt   inf   char   ima   

技术图片

 

左偏树模板题。

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

因为一个人被杀了,他就没了,为了证明他没了,所以要把他的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\n", t[get(x)].val), pop(get(x));
        }
    }
    return 0;
}

 

罗马游戏(左偏树)

标签:技术   mic   oid   int   col   idt   inf   char   ima   

原文地址:https://www.cnblogs.com/zcr-blog/p/12863564.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!