题目链接:点击查看

题目大意:给出一棵无向无根树,事先确定好了两个点 s 和 t ,现在需要通过询问找到这两个点

每次询问可以给出一个点集,系统会返回点集中距离点 s 和点 t 距离之和最小的那个点以及其距离,如果有多个符合条件的点,会返回任意一个,比如询问了点集 A = { s1 , s2 , ... , sk } ,则系统会返回一个点 v ∈ A 并且 dist( s , v ) + dist( t , v ) 最小

简单版本的是可以询问 14 次,困难版本的是只能询问 11 次

题目分析:14 和 11 次对应着数据范围 1000 ,应该是 logn 的算法,所以我们应该尽量往上面靠拢

首先因为无从下手,所以可以先问一遍全部的点,获得到一个点 rt ,且距离之和为 len,画画图应该不难看出,点 rt 满足的一个性质是,一定位于点 s 到点 v 的这条路径上

下面的转换可能比较难想,但是如果想到了的话剩下的就比较简单了

我们可以以点 rt 点为根,遍历一遍整棵树后跑出每个点的深度,此时对于每个点的深度以及 dist( s , v ) + dist( t , v ),可以看出这两个值之间满足着单调性,这样我们就可以在深度上二分找到:距离之和等于 len 的最大深度的那个点,这个点就是 s 或者 t 中的一个点,再用找到的这个点建树,询问深度为 len 的那一层的所有点,得到的答案就是另外一个点了

如果初始时设置 l = 1 , r = n ,那么 F1 就这样解决了,主要是该如何解决 F2?

很显然,询问全部的 n 个点,和知道其中一个点后再通过一次操作得到另外一个点,这两次操作是无可避免的,优化点只能出自于二分上面 ,对于二分,我们可以做的优化就是缩小初始的范围了

因为初始时找到的 rt 一定是位于 s 到 t 的路径上的,又因为我们是要借助二分寻找距离之和等于 len 的最大深度,那么当这个 rt 在 s 到 t 这条路径的最中间时,左端点最小,取到了  的位置,相应的,我们如果假设 rt 这个点初始时就是 s 点或者 t 点的话,那么右端点最多也就是 len 了,所以右端点我们设置为 min( len , max_deep ) 就好了,max_deep 是建树后的最大深度

代码:

#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
using namespace std;typedef long long LL;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const int N=1e3+100;int n,max_deep;vector<int>node[N],deep[N];pair<int,int> query(int dep)
{printf("? %d",deep[dep].size());for(auto v:deep[dep])printf(" %d",v);puts("");fflush(stdout);int rt,len;scanf("%d%d",&rt,&len);return make_pair(rt,len);
}void dfs(int u,int fa,int dep)
{max_deep=max(max_deep,dep);deep[dep].push_back(u);for(auto v:node[u]){if(v==fa)continue;dfs(v,u,dep+1);}
}void build(int rt)
{max_deep=0;for(int i=0;i<=n;i++)deep[i].clear();dfs(rt,-1,0);
}pair<int,int> get_root()
{printf("? %d",n);for(int i=1;i<=n;i++)printf(" %d",i);puts("");fflush(stdout);int rt,len;scanf("%d%d",&rt,&len);return make_pair(rt,len);
}int main()
{
#ifndef ONLINE_JUDGE
//  freopen("input.txt","r",stdin);
//  freopen("output.txt","w",stdout);
#endif
//  ios::sync_with_stdio(false);int w;cin>>w;while(w--){scanf("%d",&n);for(int i=1;i<=n;i++)node[i].clear();for(int i=1;i<n;i++){int u,v;scanf("%d%d",&u,&v);node[u].push_back(v);node[v].push_back(u);}pair<int,int>temp=get_root();int rt=temp.first,len=temp.second;build(rt);int l=(len+1)/2,r=min(max_deep,len),s;while(l<=r){int mid=l+r>>1;temp=query(mid);int p=temp.first,d=temp.second;if(d==len){s=p;l=mid+1;}elser=mid-1;}build(s);int t=query(len).first;printf("! %d %d\n",s,t);fflush(stdout);scanf("%*s");}return 0;
}

CodeForces - 1370F2 The Hidden Pair (Hard Version)(交互题+二分)相关推荐

  1. Codeforces Round #504 E - Down or Right 交互题

    1023E 题意: 交互题.在一个有障碍地图中,问如何走才能从(1,1)走到(n,n),只能向右或者向左走.每次询问两个点,回复你这两个点能不能走通. 思路: 只用最多2*n-2次询问.从(1,1), ...

  2. Codeforces1486 C1.Guessing the Greatest (easy version)(交互题+二分)

    原题链接 题意: 交互题,首先电脑给出序列的长度n.你可以询问区间[l,r]的次大值位置,求序列最大值的位置. 思路: 首先考虑最简单的情况,当区间长度为2时,那么假设区间为[l,r].当询问的次大值 ...

  3. 【交互题+二分】Codeforces Round #516 E. Dwarves, Hats and Extrasensory Abilities

    Codeforces Round #516 E. Dwarves, Hats and Extrasensory Abilities 题意: 输出一个点,输入是黑色或者白色,n次询问后,输出一条直线,是 ...

  4. D1. RPD and Rap Sheet (Easy Version) (交互题+构造)

    题意: 交互题,有一个初始密码xxx,只有nnn次猜测机会,假如猜了yyy,x!=yx!=yx!=y,那么密码就会变成x⨁yx\bigoplus yx⨁y. 题解: 设第iii次猜测的数为pip_ip ...

  5. Codeforces ~ 1063C ~ Dwarves, Hats and Extrasensory Abilities (交互题,二分)

    题意 交互题.N次,让你每次输出一个点的坐标,然后他告诉你当前点的颜色(黑或白).使得可以找到一条直线把黑点和白点分隔开.最终输出这条直线过的两个点.输入输出均为正数,分为为0~1e9 思路 我们把所 ...

  6. CF1039B:交互题+二分

    CF1039B 题解: 第二次做交互题,对交互题没什么感觉.你要询问系统,所以你cout输入,系统再立刻给你cin答案.交互题格式就在于要清空缓存区,可以在printf输出完之后,加一fflush(s ...

  7. CF1370F2-The Hidden Pair(Hard Version)【交互题,二分】

    正题 题目链接:https://www.luogu.com.cn/problem/CF1370F2 题目大意 TTT组数据,给出nnn个点的一棵树,有两个隐藏的关键点.你每次可以询问一个点集,交互库会 ...

  8. Codeforces A - Bear and Prime 100(交互题)

    A - Bear and Prime 100 思路:任何一个合数都可以写成2个以上质数的乘积.在2-100中,除了4,9,25,49外都可以写成两个以上不同质数的乘积. 所以打一个质数加这四个数的表: ...

  9. CF1019B:交互题+二分

    CF1019B 题解: 任意两个人之间相差一个数字,手写模拟一下,可以发现规律.就是相对的两个人之间差值为-2,0,2. 如果n = 4k+2,一定无解.因为它和对面的数字相差2k+1奇数个,根据奇偶 ...

最新文章

  1. input[type=checkbox] ; input[type=radio] 改变默认样式
  2. python root_python在非root权限下的安装方法
  3. jquery Ajax 通过jsonp的方式跨域提交表单
  4. deepin v20.4设置全局搜索的快捷键
  5. 我的第一个可用的Windows驱动完成了
  6. java camel swagger,java – CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES没有反映在swagger.json中
  7. 不会玩游戏的程序员不是好作家,《深入理解Java虚拟机》周志明来了!
  8. vonic 环境配置_vonic单页面应用
  9. mini 打开窗口提交表单,按钮在页脚
  10. AForge.net简介和认识
  11. popwindow高度_使用Style实现的popwindow弹出和收起的动画效果
  12. 9008刷机 小米max2_小米max2线刷包_小米max2刷机包_小米max2固件包_小米max2救砖包 - 线刷宝ROM中心...
  13. windows 10 提升管理员权限
  14. AAE 对抗自编码(一)
  15. 基于stm32蓝牙智能小车设计
  16. GitChat · 安全 | 基于机器学习的 Webshell 发现技术探索
  17. 如何理解光圈、ISO、快门、曝光这几个概念?
  18. 2023安徽大学计算机考研信息汇总
  19. trx40主板支持服务器内存,华硕发布TRX40系列主板:8内存插槽设计+64个PCIe 4.0通道...
  20. 积累的力量(《把时间当作朋友》读书笔记)

热门文章

  1. CORS 跨域-哪些操作受到同源限制
  2. SpringSecurity案例之认证服务搭建
  3. MyBatis 源码解读-带着问题去看源码
  4. 学习AOP 之前必须明白的几个概念
  5. @Conditional进行条件判断等
  6. RocketMQ各角色介绍
  7. 百万数据报表:分析以及解决办法
  8. 封装案例-创建士兵类-完成初始化方法
  9. Redisson框架快速入门
  10. Spring Schedule关闭订单