CF1174F Ehab and the Big Finale

Posted hanker99

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF1174F Ehab and the Big Finale相关的知识,希望对你有一定的参考价值。

https://codeforces.com/contest/1174/problem/F

 题意: 交互题,给出一棵树,1为树根,有一点x为目标点。

有两种操作 d a: 询问a到x的距离,s a:询问从a到x的路径上第二个结点的编号,注意a必须要是x的祖先结点。

需要在36次询问内给出x结点

思路:先从树根开始一次dfs,sz数组维护以i为根节点的树拥有的结点数(包括i本身)。 询问一次d 1,得到x的深度depx

然后从树根开始,每次经过sz值最大的子节点,直到该路径的终点v,并询问d v 得到dist(x,v).

因为我们现在知道depv,depx,dist(x,v),那么我们可以知道y=lca(v,x)的深度depy, dist(x,v)=depx+depv2depy

因为该路径上的所有点深度都不同,所以我们可以得到y点的位置,询问s y,得到从y到x路径上第二个结点的编号。

进行下一次dfs,当depv==depx时,x的位置便是该次dfs上路径的唯一点。于是我们得到x的位置技术图片

技术图片

 

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+5;
vector<int> v[maxn],h;
int sz[maxn],dep[maxn],depx;
int pre(int node,int p) sz[node]=1; for(int u:v[node]) if(u!=p) dep[u]=dep[node]+1; sz[node]+=pre(u,node); return sz[node]; int query(char c,int u) printf("%c %d\\n",c,u); fflush(stdout); int ans; scanf("%d",&ans); return ans; void get(int node) h.push_back(node); int big=-1; for(int u:v[node]) if(sz[node]>sz[u]&&(big==-1||(sz[u]>sz[big]))) big=u; if(big!=-1) get(big); int dfs(int node) h.clear(); get(node); int depy=(depx+dep[h.back()]-query(‘d‘,h.back()))/2,y=h[depy-dep[node]]; if (depx==depy) return y; return dfs(query(‘s‘,y)); int main() //freopen("datain.txt", "r", stdin); int n;scanf("%d",&n); for(int i=1;i<n;i++) int a,b; scanf("%d%d",&a,&b); v[a].push_back(b); v[b].push_back(a); depx=query(‘d‘,1); pre(1,0); printf("! %d\\n",dfs(1)); fflush(stdout);

 

以上是关于CF1174F Ehab and the Big Finale的主要内容,如果未能解决你的问题,请参考以下文章

CF1174D Ehab and the Expected XOR Problem - 构造

CF.862D.Mahmoud and Ehab and the binary string(交互 二分)

cf 1174 D Ehab and the Expected XOR Problem

CF D. Ehab and the Expected XOR Problem 贪心+位运算

[CF959E] Mahmoud and Ehab and the xor-MST - 贪心,最小生成树

CF1174E Ehab and the Expected GCD Problem(DP,数论)