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

转载于:https://www.cnblogs.com/hanker99/p/10981902.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值