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 [题目大意] 现在有 一群互不认识的猴子,每个猴子有一个能力值,每次选择两个猴子,挑出他们所 ...
随机推荐
- git修改commit说明
当发现说明写错了时,执行git commit --amend,然后修改说明即可.
- Android笔记之Retrofit与RxJava的组合
依赖 implementation 'com.squareup.retrofit2:retrofit:2.5.0' implementation 'com.squareup.retrofit2:con ...
- BZOJ1217: [HNOI2003]消防局的设立
BZOJ1217: [HNOI2003]消防局的设立 Description 2020年,人类在火星上建立了一个庞大的基地群,总共有n个基地. 起初为了节约材料,人类只修建了n-1条道路来连接这些基地 ...
- CUDA: 流
1. 页锁定主机内存 c库函数malloc()分配标准的,可分页(Pagable)的内存,cudaHostAlloc()分配页锁定的主机内存.页锁定内存也称为固定内存(Pinned Memory)或者 ...
- Bitmaps
核心知识点: 1.Bitmaps是一种特殊的“数据结构”,实质上是一个字符串,操作单元是位. 2.命令: a.setbit:设置值,只能存储0和1,适用二元判断类型 b.getbit:获取值 c.bi ...
- 前端JSONPJIE解决跨域问题
解决同源策略的两个方法 1 . JSONP jsonp (将 JSON 数据填充进回调函数,这就是JSONP的JSON+Padding 的含义) jsonp是json用来跨域的一个东西,原理是通过sc ...
- 后端CORS解决跨域问题
一 . 为什么会有跨域问题 是因为浏览器的同源策略是对ajax请求进行阻拦了,但是不是所有的请求都给做跨域,像是一般的href 属性,a标签什么的都不拦截. 二 . 解决跨域的方法 解决跨域有两种方法 ...
- Algorithm: dynamic programming
1. Longest Increasing Subsequence (LIS) problem unsorted array, calculate out the maximum length of ...
- lk进kernel
-- ] [upmu_is_chr_det] [] DRAM Rank : [] DRAM Rank[] Start = 0x40000000, Size = 0x25fc0000 [] DRAM R ...
- 2048plus,可以直接分享到微信的2048
点击图片下载apk包!!