当前位置:网站首页>【洛谷】P1456 Monkey King
【洛谷】P1456 Monkey King
2022-08-09 02:41:00 【记录算法题解】
题目地址:
https://www.luogu.com.cn/problem/P1456
题面翻译:
题目描述:
曾经在一个森林中居住着 N N N只好斗的猴子。在最初他们我行我素,互不认识。但是猴子们不能避免争吵,且两只猴子只会在不认识对方时发生争吵,当争吵发生时,双方会邀请它们各自最强壮的朋友并发起决斗(决斗的为各自最强壮的朋友)。当然,在决斗之后两只猴子和他们各自的伙伴都认识对方了(成为朋友),虽然他们曾经有过冲突,但是他们之间绝不会再发生争吵了。
假设每只猴子有一个强壮值,强壮值将在一场决斗后减少为原先的一半(例如 10 10 10会减少到 5 5 5,而 5 5 5会减少到 2 2 2,即向下取整)。
我们也假设每只猴子都认识它自己(是自己的朋友)。即当他是他朋友中最强壮的,他自己就会去决斗。
输入格式:
有多组数据,每一组数据有两部分。
第一部分:第一行包含一个整数 N N N表示猴子的数量。后为 N N N行,每行一个数字为第 i i i只猴子的强壮值 s i s_{i} si。
第二部分:第一行包含一个整数 M M M表示发生了 M M M次冲突。后为 M M M行,每行两个整数 x x x和 y y y,表示第 x x x只猴子和第 y y y只猴子之间发生了冲突。
输出格式:
对于每次冲突,如果两只猴子认识对方,输出-1
,否则输出决斗后他们朋友中最强壮的猴子的强壮值。
数据范围:
N , M ≤ 100000 N,M\leq 100000 N,M≤100000, s i ≤ 32768 s_{i}\leq 32768 si≤32768
题目描述:
Once in a forest, there lived N N 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 each other. And when it happens, both the two monkeys will invite the strongest friend of them, and duel. Of course, after the duel, the two monkeys and all of there friends knows each other, and the quarrel above will no longer happens between these monkeys even if they have ever conflicted.
Assume that every money has a strongness value, which will be reduced to only half of the original after a duel(that is, 10 10 10 will be reduced to 5 5 5 and 5 5 5 will be reduced to 2 2 2).
And we also assume that every monkey knows himself. That is, when he is the strongest one in all of his friends, he himself will go to duel.
输入格式:
There are several test cases, and each case consists of two parts.
First part: The first line contains an integer N ( N ≤ 100 , 000 ) N(N\le 100,000) N(N≤100,000), which indicates the number of monkeys. And then N N N lines follows. There is one number on each line, indicating the strongness value of ith monkey( ≤ 32768 \le 32768 ≤32768).
Second part: The first line contains an integer M ( M ≤ 100 , 000 ) M(M\le 100,000) M(M≤100,000), which indicates there are M M M conflicts happened. And then M M M lines follows, each line of which contains two integers x x x and y y y, indicating that there is a conflict between the X X Xth monkey and Y Y Yth.
输出格式:
For each of the conflict, output − 1 -1 −1 if the two monkeys know each other, otherwise output the strength value of the strongest monkey among all of its friends after the duel.
可以用左倾堆 + 并查集,这里需要用大顶堆,每个并查集对应一个大顶堆,并且维护并查集的树根即为该大顶堆的堆顶。每次询问的时候,先查询一下 x x x和 y y y所在堆的堆顶,这两个即为强壮值最大的两个猴子(如果堆顶相等则说明不需要决斗),做决斗的时候,先合并 x x x和 y y y的左右子堆,最后将 x x x和 y y y的强壮值减半,再合并进去。并查集的维护只需要直接将 x x x和 y y y还有最终合并出来的堆的堆顶 t t t的父亲全连到 t t t上即可。代码如下:
#include <iostream>
using namespace std;
const int N = 1e5 + 10;
int n, m;
int v[N], d[N], l[N], r[N];
int p[N];
int find(int x) {
if (p[x] != x) p[x] = find(p[x]);
return p[x];
}
int merge(int x, int y) {
if (!x || !y) return x ^ y;
if (v[x] < v[y]) swap(x, y);
r[x] = merge(r[x], y);
if (d[l[x]] < d[r[x]]) swap(l[x], r[x]);
d[x] = d[r[x]] + 1;
return x;
}
int main() {
while (~scanf("%d", &n)) {
for (int i = 1; i <= n; i++) {
scanf("%d", &v[i]);
p[i] = i;
d[i] = 1;
l[i] = r[i] = 0;
}
scanf("%d", &m);
while (m--) {
int x, y;
scanf("%d%d", &x, &y);
x = find(x), y = find(y);
if (x == y) puts("-1");
else {
int t = merge(merge(l[x], l[y]), merge(r[x], r[y]));
l[x] = r[x] = l[y] = r[y] = 0;
v[x] /= 2, v[y] /= 2;
t = merge(t, merge(x, y));
p[x] = p[y] = p[t] = t;
printf("%d\n", v[t]);
}
}
}
}
每次操作时间复杂度 O ( log N ) O(\log N) O(logN),空间 O ( N ) O(N) O(N)。
边栏推荐
- Redis - 时间序列数据类型的保存方案和消息队列实现
- The building had been registry cluster, load balancing
- 2022年最流行的自动化测试工具有哪些?全网最全最细都在这里了
- 数字 05 verilog&vivado2018.2零散笔记
- DSP28379学习笔记 (一)——GPIO基本操作
- Appium常用操作及H5页面元素定位
- Open3D 均匀采样
- 为什么应用程序依赖关系映射对于云迁移至关重要
- 2022年自然语言处理校招社招实习必备知识点盘点分享
- "Lonely Walking on the Moon": Two choices of Duguyue, let a "middleman" become a big hero
猜你喜欢
OpenLORIS-Object Datasets
多线程 (进阶+初阶)
历史最全DL相关书籍、课程、视频、论文、数据集、会议、框架和工具整理分享
The first lesson of HNUMSC-C language
企业从云服务的承诺支出中获得最大收益的四种方法
Jenkins configuration nail notification
online schema change and create index
Programmer's Daily Life | Daily Fun
【izpack】使用izpack为你的程序提供安装程序封装
"Lonely Walking on the Moon": Two choices of Duguyue, let a "middleman" become a big hero
随机推荐
Apache站点下载大文件自动中断或者文件不完整
Flume (四) --------- Flume 企业开发案例
Jenkins配置钉钉通知
Open3D 均匀采样
grafana的panel点击title,没有反应,没有出现edit选项
Likou Brush Question Record 4.1-----209. The sub-array with the smallest length
SQLite切换日志模式优化
What are the most popular automated testing tools in 2022?The most complete and most detailed of the entire network is here
数字 01 Vivado2018.2安装及实操
OJ:L3-001 凑零钱 DFS
时间复杂度和空间复杂度
自动化测试框架总结
Open3D 点云曲率计算
如何最大限度地减少企业受到供应链攻击的风险
20220530设计问题:常数时间插入、删除和获取随机元素
Json之JArray的使用方法
gpio子系统和pinctrl子系统(中)
【HNUMSC】C language second lecture
1261. 在受污染的二叉树中查找元素
通过安装VNC服务器x11vnc(或vnc4server)和配置x11vnc.service实现远程通过VNC-Viewer访问VNC服务器。