HDU 1512 Monkey King (左偏树+并查集)
题意:在一个森林里住着N(N<=10000)只猴子。在一开始,他们是互不认识的。但是随着时间的推移,猴子们少不了争斗,但那只会发生在互不认识
(认识具有传递性)的两只猴子之间。争斗时,两只猴子都会请出他认识的猴子里最强壮的一只(有可能是他自己)进行争斗。争斗后,这两只猴子就互相认识。
每个猴子有一个强壮值,但是被请出来的那两只猴子进行争斗后,他们的强壮值都会减半(例如10会减为5,5会减为2)。现给出每个猴子的初始强壮值,
给出M次争斗,如果争斗的两只猴子不认识,那么输出争斗后两只猴子的认识的猴子里最强壮的猴子的强壮值,否则输出 -1。
析:我们可以通过并查集来判断是不是同一群,然后由于要改值和合并,要有一个合适的数据结构来维护,很容易想到是用左偏树,不过好像Splay也行。
代码如下:
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <cstring>
#include <set>
#include <queue>
#include <algorithm>
#include <vector>
#include <map>
#include <cctype>
#include <cmath>
#include <stack>
#include <sstream>
#define debug() puts("++++");
#define gcd(a, b) __gcd(a, b)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define freopenr freopen("in.txt", "r", stdin)
#define freopenw freopen("out.txt", "w", stdout)
using namespace std; typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> P;
const int INF = 0x3f3f3f3f;
const double inf = 0x3f3f3f3f3f3f;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int maxn = 100000 + 10;
const int mod = 1e6 + 10;
const int dr[] = {-1, 0, 1, 0};
const int dc[] = {0, 1, 0, -1};
const char *de[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};
int n, m;
const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
inline bool is_in(int r, int c){
return r >= 0 && r < n && c >= 0 && c < m;
}
int p[maxn];
int Find(int x){ return x == p[x] ? x : p[x] = Find(p[x]); }
struct Node{
int key, l, r, fa, d;
};
Node tr[maxn]; int iroot(int i){
if(i == -1) return i;
while(tr[i].fa != -1) i = tr[i].fa;
return i;
} int Merge(int rx, int ry){
if(rx == -1) return ry;
if(ry == -1) return rx;
if(tr[rx].key < tr[ry].key) swap(rx, ry);
int r = Merge(tr[rx].r, ry);
tr[rx].r = r; tr[r].fa = rx;
if(tr[r].d > tr[tr[rx].l].d) swap(tr[rx].r, tr[rx].l);
if(tr[rx].r == -1) tr[rx].d = 0;
else tr[rx].d = tr[tr[rx].r].d + 1;
return rx;
} int Insert(int i, int key, int root){
tr[i].key = key;
tr[i].l = tr[i].r = tr[i].fa = -1;
tr[i].d = 0;
return Merge(root, i);
} int del(int i){
if(i == -1) return -1;
int l = tr[i].l, r = tr[i].r, y = tr[i].fa;
tr[i].l = tr[i].r = tr[i].fa = -1;
int x;
tr[x = Merge(l, r)].fa = y;
if(y != -1 && tr[y].l == i) tr[y].l = x;
if(y != -1 && tr[y].r == i) tr[y].r = x;
for( ; y != -1; x = y, y = tr[y].fa){
if(tr[tr[y].l].d < tr[tr[y].r].d) swap(tr[y].l, tr[y].r);
if(tr[y].d == tr[tr[y].r].d + 1) break;
tr[y].d = tr[tr[y].r].d + 1;
}
if(x != -1) return iroot(x);
return iroot(y);
} Node top(int root){ return tr[root]; } int add(int i){
if(i == -1) return i;
if(tr[i].l == -1 && tr[i].r == -1 && tr[i].fa == -1){
tr[i].key /= 2;
return i;
}
int key = tr[i].key / 2;
int rt = del(i);
return Insert(i, key, rt);
} void init(){
for(int i = 1; i <= n; ++i){
p[i] = i;
scanf("%d", &tr[i].key);
tr[i].l = tr[i].r = tr[i].fa = -1;
tr[i].d = 0;
}
} int main(){
while(scanf("%d", &n) == 1){
init();
scanf("%d", &m);
while(m--){
int u, v;
scanf("%d %d", &u, &v);
int x = Find(u);
int y = Find(v);
if(x == y){ printf("-1\n"); continue; }
p[y] = x;
int rt = iroot(u);
int rt1 = iroot(v);
rt = add(rt); rt1 = add(rt1);
int t = Merge(rt, rt1);
printf("%d\n", tr[t].key);
}
}
return 0;
}
HDU 1512 Monkey King (左偏树+并查集)的更多相关文章
- hdu 1512 Monkey King 左偏树
题目链接:HDU - 1512 Once in a forest, there lived N aggressive monkeys. At the beginning, they each does ...
- hdu 1512 Monkey King —— 左偏树
题目:http://acm.hdu.edu.cn/showproblem.php?pid=1512 很简单的左偏树: 但突然对 rt 的关系感到混乱,改了半天才弄对: 注意是多组数据! #includ ...
- zoj 2334 Monkey King/左偏树+并查集
原题链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1389 大致题意:N只相互不认识的猴子(每只猴子有一个战斗力值) 两只 ...
- HDU 1512 Monkey King ——左偏树
[题目分析] 也是堆+并查集. 比起BZOJ 1455 来说,只是合并的方式麻烦了一点. WA了一天才看到是多组数据. 盲人OI (- ̄▽ ̄)- Best OI. 代码自带大常数,比启发式合并都慢 [ ...
- hdu1512 Monkey King(左偏树 + 并查集)
Once in a forest, there lived N aggressive monkeys. At the beginning, they each does things in its o ...
- HDU 1512 Monkey King(左偏堆)
爱争吵的猴子 ★★☆ 输入文件:monkeyk.in 输出文件:monkeyk.out 简单对比 时间限制:1 s 内存限制:128 MB [问题描述] 在一个森林里,住着N只好斗的猴子.开始,他们各 ...
- 洛谷 - P1552 - 派遣 - 左偏树 - 并查集
首先把这个树建出来,然后每一次操作,只能选中一棵子树.对于树根,他的领导力水平是确定的,然后他更新答案的情况就是把他子树内薪水最少的若干个弄出来. 问题在于怎么知道一棵子树内薪水最少的若干个分别是谁. ...
- 洛谷 - P3377 - 【模板】左偏树(可并堆) - 左偏树 - 并查集
https://www.luogu.org/problemnew/show/P3377 左偏树+并查集 左偏树维护两个可合并的堆,并查集维护两个堆元素合并后可以找到正确的树根. 关键点在于删除一个堆的 ...
- HDU 1512 Monkey King(左偏树+并查集)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=1512 [题目大意] 现在有 一群互不认识的猴子,每个猴子有一个能力值,每次选择两个猴子,挑出他们所 ...
随机推荐
- springcloud与docker微服务架构实战--笔记
看了<微服务那些事>之后,Spring boot和Spring Cloud的关系理清楚了,Spring cloud各个模块的作用也了解了. 但是,Spring cloud 与Docker的 ...
- EasyPusher华为手机直播推流硬编码[OMX.IMG.TOPAZ.Encoder] failed to set input port definition parameters.
EasyPusher作为一款RTSP推送利器, 配合EasyDarwin开源流媒体服务器,在发布伊始,很快获得了广大人民群众的一致好评. 但是也有一些用户反映: EasyPusher在我的华为手机上会 ...
- 观察OnPaint与OnIdle与OnSize事件
import wx class SketchWindow(wx.Window): def __init__(self, parent, ID): wx.Window.__init__(self, pa ...
- Django 模型层--单表
ORM 简介 MTV或者MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库,这可以大大的减少了开 ...
- Swift 烧脑体操(二) - 函数的参数
前言 Swift 其实比 Objective-C 复杂很多,相对于出生于上世纪 80 年代的 Objective-C 来说,Swift 融入了大量新特性.这也使得我们学习掌握这门语言变得相对来说更加困 ...
- linux下安装https证书
https://www.aliyun.com/jiaocheng/165422.html
- 《CSS权威指南(第三版)》---第六章 文本属性
本章主要的内容是: 1.文本缩进: text-indent.行内元素无法缩进,一般用左内边距或外边距来创造这种效果. 2.文本对齐:text-align .只应用于块状元素. 3.行高:一般line- ...
- poj 2336 Ferry Loading II ( 【贪心】 )
Ferry Loading II Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 3704 Accepted: 1884 ...
- 吴恩达机器学习笔记(八) —— 降维与主成分分析法(PCA)
主要内容: 一.降维与PCA 二.PCA算法过程 三.PCA之恢复 四.如何选取维数K 五.PCA的作用与适用场合 一.降维与PCA 1.所谓降维,就是将数据由原来的n个特征(feature)缩减为k ...
- mooc_java 集合框架中 学生所选课程2Map&HashMap
Map&HashMapMap提供映射关系,元素以键值对形式存储,Map的键值对一Entry类型的对象实例形式存在,key值不能重复,value可以键最多能映射到一个值,支持泛型 Map< ...