Monkey King HDU - 1512 (左偏树)

Monkey King

HDU - 1512

忽然看到左偏树,挺简单的,抄了个模板题练练

 1 //左偏树
 2 #include <bits/stdc++.h>
 3 using namespace std;
 4 const int maxn = 100010;
 5 struct Node{
 6     int val, dis, l, r;
 7 }p[maxn];
 8 int f[maxn];
 9 int gf(int x){
10     return x == f[x] ? f[x] : f[x] = gf(f[x]);
11 }
12 inline void maintain(int rt){
13     f[p[rt].r] = rt;
14 }
15 int merge(int x, int y){
16     if(!x) return y;
17     if(!y) return x;
18     if(p[x].val < p[y].val) swap(x, y);
19     p[x].r = merge(p[x].r, y);
20     maintain(x);   // 维护右子树的父亲
21     int l = p[x].l, r = p[x].r;
22     if(p[l].dis < p[r].dis) swap(p[x].l, p[x].r);
23     if(p[x].r == 0) p[x].dis = 0;
24     else p[x].dis = p[p[x].r].dis + 1;
25     return x;
26 }
27 int pop(int x){
28     int l = p[x].l, r = p[x].r;
29     p[x].dis = 0;
30     p[x].l = p[x].r = 0;
31     f[l] = l; f[r] = r;   //维护父亲
32     return merge(l, r);
33 }
34 int main(){
35     int n, m;
36     while(scanf("%d", &n) != EOF){
37         for(int i = 1; i <= n; i++){
38             scanf("%d", &p[i].val);
39             p[i].l = p[i].r = p[i].dis = 0;
40             f[i] = i;
41         }
42         scanf("%d", &m);
43         while(m--){
44             int a, b;
45             scanf("%d %d", &a, &b);
46             int pa = gf(a), pb = gf(b);
47             if(pa == pb) puts("-1");
48             else{
49                 p[pa].val /= 2;
50                 p[pb].val /= 2;
51                 int l = pop(pa), r = pop(pb);
52                 l = merge(l, pa);
53                 r = merge(r, pb);
54                 l = merge(l, r);
55                 printf("%d\n", p[l].val);
56             }
57         }
58     }
59     return 0;
60 }

原文地址:https://www.cnblogs.com/yijiull/p/8353614.html

时间: 2024-08-26 14:24:15

Monkey King HDU - 1512 (左偏树)的相关文章

hdu 1512 Monkey King 左偏树

题目链接:HDU - 1512 Once in a forest, there lived N aggressive monkeys. At the beginning, they each does things in its own way and none of them knows each other. But monkeys can't avoid quarrelling, and it only happens between two monkeys who does not kn

HDU 1512 并查集+左偏树

Monkey King Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 3105    Accepted Submission(s): 1330 Problem Description Once in a forest, there lived N aggressive monkeys. At the beginning, they e

zoj2334 Monkey King , 并查集,可并堆,左偏树

提交地址:点击打开链接 题意:  N(N<=10^5)只猴子,初始每只猴子为自己猴群的猴王,每只猴子有一个初始的力量值.这些猴子会有M次会面.每次两只猴子x,y会面,若x,y属于同一个猴群输出-1,否则将x,y所在猴群的猴王的力量值减半,然后合并这两个猴群.新猴群中力量值最高的为猴王.输出新猴王的力量值. 分析:涉及集合的查询,合并,取最值. 利用并查集和左偏树即可解决. #include <cstdio> #include <cstring> #include <io

猴子大王Monkey King 左偏树+并查集维护

Description Once in a forest, there lived N aggressive monkeys. At the beginning, they each does things in its own way and none of them knows each other. But monkeys can't avoid quarrelling, and it only happens between two monkeys who does not know e

zoj 2334 Monkey King/左偏树+并查集

原题链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1389 大致题意:N只相互不认识的猴子(每只猴子有一个战斗力值) 两只不认识的猴子之间发生冲突,两只猴子会分别请出它们认识的最强壮的 猴子进行决斗.决斗之后这,两群猴子都相互认识了. 决斗的那两只猴子战斗力减半...有m组询问 输入a b表示猴子a和b发生了冲突,若a,b属于同一个集合输出-1 否则输出决斗之后这群猴子(已合并)中最强的战斗力值... 具体思路:用并查

[HDU1512]Monkey King(左偏树)

用并查集维护猴子们的关系,强壮值用左偏树维护就行了 Code #include <cstdio> #include <algorithm> #include <cstring> #define N 100010 using namespace std; int n,fa[N],m,fr[N]; //fr[x]维护猴子x所在集合在左偏树上的编号 int Find(int x){return x==fa[x]?x:fa[x]=Find(fa[x]);} namespace

HDU 5818 Joint Stacks(左偏树)

题目链接:点击打开链接 思路: 该题的关键是怎么把两个栈合并, 我们可以使用一种叫左偏树的数据结构, 满足堆的性质和集合的性质,支持在O(logn)的复杂度下进行删除堆顶元素, 插入一个元素,合并两个堆. 细节参见代码: #include <bits/stdc++.h> using namespace std; typedef pair<int, int> P; const int maxn = 152400; P v[maxn]; int tot, u, a, b, l[maxn

【左偏树】HDU1512-Monkey King

[题目大意] 在一个森林里住着N(N<=10000)只猴子.在一开始,他们是互不认识的.但是随着时间的推移,猴子们少不了争斗,但那只会发生在互不认识(认识具有传递性)的两只猴子之间.争斗时,两只猴子都会请出他认识的猴子里最强壮的一只(有可能是他自己)进行争斗.争斗后,这两只猴子就互相认识.每个猴子有一个强壮值,但是被请出来的那两只猴子进行争斗后,他们的强壮值都会减半(例如10会减为5,5会减为2).现给出每个猴子的初始强壮值,给出M次争斗,如果争斗的两只猴子不认识,那么输出争斗后两只猴子的认识的

左偏树

概要:左偏树是具有左偏性质的堆有序二叉树,它相比于优先队列,能够实现合并堆的功能. 先仪式型orzorzozr国家集训队论文https://wenku.baidu.com/view/515f76e90975f46527d3e1d5.html 左偏树的节点定义: 1 struct node { 2 int lc, rc, val, dis; 3 } LTree[maxn]; 左偏树的几个基本性质如下: 节点的键值小于等于它的左右子节点的键值 节点的左子节点的距离不小于右子节点的距离 节点的距离等于