题解:CF1370F2 The Hidden Pair (Hard Version)

2024-05-26 03:36

本文主要是介绍题解:CF1370F2 The Hidden Pair (Hard Version),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题意

交互题。 给你一棵 n n n 个点的树,需要得出树上两个点 X , Y X,Y X,Y 的位置。你可以向评测机询问一个点集,评测机会回答点集中与 X , Y X,Y X,Y 距离和最小的点,以及这个距离和。询问不超过 11 11 11 次。

思路

询问次数不能超过 11 11 11 次,这个数字与 log ⁡ n \log n logn 的值很接近。考虑先对所有 n n n 个点进行询问,这样就可以得到 X , Y X,Y X,Y 之间的距离,和一个必定在 X , Y X,Y X,Y 路径上的点。设这个点为 r t rt rt X , Y X,Y X,Y 之间的距离为 d i s dis dis。如果我们以 r t rt rt 为树根,那么对于树中深度为 d e p dep dep 的点集 { A } \{A\} {A},且 d e p dep dep 大于等于 X , Y X,Y X,Y 中较小的深度,我们对其进行询问:

  • 如果询问得到的距离和为 d i s dis dis,则表示询问得到的点在 X , Y X,Y X,Y 的路径上,即 X , Y X,Y X,Y 中较大的深度大于等于 d e p dep dep
  • 如果询问得到的距离和大于 d i s dis dis,则表示该深度的点中没有在 X , Y X,Y X,Y 的路径上的,即 X , Y X,Y X,Y 中较大深度小于 d e p dep dep

对于第一种情况询问到的点都可能是 X , Y X,Y X,Y 中深度较大的点,不妨令 d e p X ≥ d e p Y dep_X\ge dep_Y depXdepY。考虑二分,区间为 [ ⌊ d i s 2 ⌋ , min ⁡ ( d i s , D e p ) ] [\lfloor\cfrac{dis}{2}\rfloor,\min(dis,Dep)] [⌊2dis,min(dis,Dep)],其中 D e p Dep Dep 为最大深度。每一轮都询问一次深度为 m i d mid mid 的点集,按照上述两种情况二分,最终可以得到深度较大的 X X X。然后我们以 X X X 为树根,然后询问深度为 d i s dis dis 的点集,得到的点即为 Y Y Y

为什么二分区间上界可以这么取?

感性理解一下,因为我们要处理出 X , Y X,Y X,Y 较深的一个点,所以深度小于 d i s ( X , Y ) dis(X,Y) dis(X,Y) 的点都不会是那个较深的点。

实现

实现没什么难点,注意每次询问/回答都要 fflush(stdout)

代码

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1005;
vector<int> mp[maxn << 1];
void addEdge(int u,int v) {mp[u].push_back(v);
}
vector<int> a[maxn]; int Dep;
void dfs(int u,int fa,int dep) {a[dep].push_back(u);Dep = max(Dep,dep);for (auto v : mp[u]) {if (v == fa) continue;dfs(v,u,dep + 1);}
}
pair<int,int> Query(const vector<int> &ask) {printf("? %d",ask.size());for (auto x : ask) printf(" %d",x);puts(""); fflush(stdout);int x,d;scanf("%d %d",&x,&d);return make_pair(x,d);
}
pair<int,int> Solve(int n,const vector<pair<int,int> > &edge) {for (int i = 1;i <= n;i ++)mp[i].clear();for (int i = 0;i <= Dep;i ++) a[i].clear();Dep = 0;for (auto E : edge) {int u = E.first, v = E.second;addEdge(u,v); addEdge(v,u);}vector<int> ask;for (int i = 1;i <= n;i ++) ask.push_back(i);pair<int,int> res = Query(ask);int rt = res.first, sum = res.second;dfs(rt,0,0);int l = sum >> 1, r = min(Dep,sum);int X = 0;while (l <= r) {int mid = l + r >> 1;res = Query(a[mid]);if (res.second == sum) l = mid + 1, X = res.first;else r = mid - 1;}for (int i = 0;i <= Dep;i ++) a[i].clear();Dep = 0; dfs(X,0,0);return make_pair(X, Query(a[sum]).first);
}
int T,n; char AC_or_WA[maxn];
vector<pair<int,int> > Edge;
int main() {scanf("%d",&T);while (T --) {scanf("%d",&n);Edge.clear();for (int i = 1,u,v;i < n;i ++) {scanf("%d%d",&u,&v);Edge.emplace_back(u,v);}pair<int,int> ans = Solve(n,Edge);printf("! %d %d\n",ans.first,ans.second);fflush(stdout);scanf("%s",AC_or_WA + 1);}return 0;
}

这篇关于题解:CF1370F2 The Hidden Pair (Hard Version)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1003423

相关文章

LeetCode11. 盛最多水的容器题解

LeetCode11. 盛最多水的容器题解 题目链接: https://leetcode.cn/problems/container-with-most-water 示例 思路 暴力解法 定住一个柱子不动,然后用其他柱子与其围住面积,取最大值。 代码如下: public int maxArea1(int[] height) {int n = height.length;int

LeetCode:经典题之141、142 题解及延伸

系列目录 88.合并两个有序数组 52.螺旋数组 567.字符串的排列 643.子数组最大平均数 150.逆波兰表达式 61.旋转链表 160.相交链表 83.删除排序链表中的重复元素 389.找不同 1491.去掉最低工资和最高工资后的工资平均值 896.单调序列 206.反转链表 92.反转链表II 141.环形链表 142.环型链表 目录 系列目录141. 环形链表常量因子 1

Java compiler level does not match the version of the installed Java project facet. map解决方法

右键项目“Properties”,在弹出的“Properties”窗口左侧,单击“Project Facets”,打开“Project Facets”页面。 在页面中的“Java”下拉列表中,选择相应版本就OK了。

C语言 | Leetcode C语言题解之第188题买卖股票的最佳时机IV

题目: 题解: int maxProfit(int k, int* prices, int pricesSize) {int n = pricesSize;if (n == 0) {return 0;}k = fmin(k, n / 2);int buy[k + 1], sell[k + 1];memset(buy, 0, sizeof(buy));memset(sell, 0, size

6月21日训练 (东北林业大学)(个人题解)

前言:   这次训练是大一大二一起参加的训练,总体来说难度是有的,我和队友在比赛时间内就写出了四道题,之后陆陆续续又补了了三道题,还有一道题看了学长题解后感觉有点超出我的能力范围了,就留给以后的自己吧。话不多说,上正文。 正文:   Problem:A 幸运数字: #include <bits/stdc++.h>using namespace std;int sum,ans;in

LeetCode:经典题之389 题解与延伸

系列目录 88.合并两个有序数组 52.螺旋数组 567.字符串的排列 643.子数组最大平均数 150.逆波兰表达式 61.旋转链表 160.相交链表 83.删除排序链表中的重复元素 389.找不同 1491.去掉最低工资和最高工资后的工资平均值 896.单调序列 206.反转链表 92.反转链表II 141.环形链表 142.环型链表 目录 系列目录389.找不同哈希表

由于jdk版本问题引起的Unsupported major.minor version 52.0

tomcat启动报错 错误日志信息: 三月 01, 2019 9:47:02 下午 org.apache.catalina.core.ApplicationContext log INFO: Initializing Spring root WebApplicationContext 三月 01, 2019 9:47:08 下午 org.apache.catalina.core.Standard

Google Code Jam 2014(附官方题解)

2014年Google编程挑战赛 Problem A. Magic Trick Confused? Read the quick-start guide. Small input 6 points You have solved this input set. Note: To advance to the next rounds, you will need to s

Codeforces April Fools Day Contest 2014(附官方题解)

Codeforces2014年愚人节的坑题。。。但还是感觉挺好玩的。。。 A. The Great Game time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Two teams mee

【华东南AWDP】第十七届全国大学生信息安全竞赛 CISCN 2024 创新实践能力赛区域赛 部分题解WP

前言:这次区域赛AWDP安恒作为支持,赛制风格遵循安恒,一小时check一次。室温35°在室内坐了8小时,午饭是藿香正气水拌冰水。这场总体下来中规中矩吧。 WEB-welcome-BREAK Ctrl+U拿到flag WEB-submit-BREAK 文件上传,简单绕过 绕过就两个,一个MIMA头,一个等号换php(短标签) WEB-submit-FIX 修两个点,一个是