zoukankan      html  css  js  c++  java
  • CF1370F The Hidden Pair 题解

    Codeforces F1
    Codeforces F2
    Luogu F1
    Luogu F2

    Description.

    树上交互,有两个标记点。
    每次你询问一个点集,每次返回这个点集中到两标记距离和最小的点和这个距离和。
    F1 \(14\) F2 \(11\) 次内询问出两个标记点。

    Solution.

    首先,什么信息都没有的情况下肯定很困难。
    我们先询问全集,以返回的最小点为根,这样两个标记点就在两棵子树内,同时知道了链长。
    考虑 binary search,二分较大目标点的深度。
    每次可以把这层所有点拿出来问。
    判断 dis 是不是和链长相等来判断较深的那个点是不是在这个深度以下。
    这样需要 \(1+\log n+1 \approx 12\) 次,可以通过 F1。

    考虑较深那个点的值域,发现 \(\in[\frac {dis}2,dis]\),然后就节约了二分的一次。

    Coding.

    点击查看代码
    //Coded by leapfrog on 2021.10.29 {{{
    //是啊,你就是那只鬼了,所以被你碰到以后,就轮到我变成鬼了
    #include<bits/stdc++.h>
    using namespace std;typedef long long ll;
    template<typename T>inline void read(T &x)
    {
    	x=0;char c=getchar(),f=0;
    	for(;c<48||c>57;c=getchar()) if(!(c^45)) f=1;
    	for(;c>=48&&c<=57;c=getchar()) x=(x<<1)+(x<<3)+(c^48);
    	f?x=-x:x;
    }
    template<typename T,typename...L>inline void read(T &x,L&...l) {read(x),read(l...);}//}}}
    const int N=1005;int as[N],at,dis;vector<int>d[N];
    struct edge{int to,nxt;}e[N<<1];int n,et,head[N],rx,fg[N];
    inline void adde(int x,int y) {e[++et]=(edge){y,head[x]},head[x]=et;}
    inline pair<int,int> ask()
    {
    	printf("? %d ",at);for(int i=1;i<=at;i++) printf("%d%c",as[i],i==at?'\n':' ');
    	fflush(stdout);int u,v;read(u,v);return make_pair(u,v);
    }
    inline void answer(int x,int y)
    {
    	printf("! %d %d\n",x,y),fflush(stdout);char ch[10];
    	scanf("%s",ch);if(*ch=='I') exit(0);
    }
    inline void dfs0(int x,int fa,int dep,int rt)
    {
    	d[dep].push_back(x),fg[x]=rt;
    	for(int i=head[x];i;i=e[i].nxt) if(e[i].to!=fa) dfs0(e[i].to,x,dep+1,rt);
    }
    inline char check(int w)
    {
    	if(d[w].empty()) return 0;else at=d[w].size();
    	for(int i=1;i<=at;i++) as[i]=d[w][i-1];
    	pair<int,int>q=ask();if(q.second==dis) return rx=q.first,1;else return 0;
    }
    inline void solve()
    {
    	read(n),et=0;for(int i=1;i<=n;i++) head[i]=fg[i]=0;
    	for(int i=1,x,y;i<n;i++) read(x,y),adde(x,y),adde(y,x);
    	at=n;for(int i=1;i<=n;i++) as[i]=i,d[i].clear();
    	pair<int,int>q=ask();int rt=q.first;dis=q.second;
    	int l=(dis+1)/2,r=dis+1,rs=r;d[1].push_back(rt);
    	for(int i=head[rt];i;i=e[i].nxt) dfs0(e[i].to,rt,2,e[i].to);
    	while(l<=r) {int md=(l+r)>>1;if(check(md)) rs=md,l=md+1;else r=md-1;}
    	int ds=dis-rs+2;at=0;
    	for(size_t i=0;i<d[ds].size();i++) if(fg[d[ds][i]]^fg[rx]) as[++at]=d[ds][i];
    	q=ask(),answer(rx,q.first);
    }
    int main() {int Ca;for(read(Ca);Ca--;) solve();return 0;}
    
  • 相关阅读:
    Python3开发环境及基本语法(一)
    PostMan接口测试工具
    Jmeter接口测试(三)
    Jmeter接口测试(二)
    Jmeter接口测试(一)
    Fiddler抓包工具
    HTTP协议数据结构分析
    CentOS7种搭建FTP服务器
    CentOS7 apache创建虚拟路径
    CentOS7上搭建WordPress博客
  • 原文地址:https://www.cnblogs.com/pealfrog/p/15481890.html
Copyright © 2011-2022 走看看