首页 > 其他分享 >【PER #1】捉迷藏 / Ptz2022 Day1.Kyoto U L 题解

【PER #1】捉迷藏 / Ptz2022 Day1.Kyoto U L 题解

时间:2023-02-01 22:35:25浏览次数:62  
标签:rt Ptz2022 dep 题解 ll dfs fa Kyoto 备选

今天心血来潮想改一改 pj 的题,发现了这场 easy round 的 A 还没改……


跟自己和解了,想了两天没想明白,说说大致思路。

题目链接

只考虑一组询问怎么做,先把 \(v\) 当作根,称那些始终满足距离条件的点就做“备选点”。

首先第一步 \(B\) 肯定要选定一个儿子走下去,然后根据获得的距离信息再做抉择。假设现在走到了 \(u\),如果“备选点”还在 \(u\) 的子树内,那么跟第一步一样,还是需要选定一个儿子走下去。

所以最坏情况下,\(B\) 会往下走 \(h=\lfloor \frac{d-1}{2} \rfloor\) 步,此时再往下走就寄了。

同时,\(B\) 在“备选点”还在子树内的时候,不会在中途往回走。因为最终时间取决于 \(A\) 追上来的时间,\(B\) 只要确定终点,无论中途怎么走,\(A\) 都会朝 \(B\) 即终点方向走,除非 \(B\) 玩脱了让 \(A\) 堵住了通往终点的路。

所以现在相当于要确定一个从 \(v\) 往下长度为 \(h\) 的路径,当“备选点”还在 \(u\) 子树内时让 \(u\) 沿这条路径走。

当然,除了上面的情况,还有可能 \(B\) 走着走着发现“备选点”不在下面了,此时 \(B\) 有两种抉择:

  • 铁了心往下面走

  • 赶紧回头碰碰运气,看能不能在 \(A\) 追上来前走一条更长的路。

实际上第二种走法非常劣,如果选择了回头走更长的路,那还不如一开始就走这条更长的路,这样更不容易被 \(A\) 抓到,反正用时也一样(与前面分析不会往回走一样)。所以一旦 \(B\) 发现“备选点”不在下面了,就会往子树内最深的叶子走。

所以如上分析,\(B\) 一开始就会朝着最远点走,且一定会走 \(h\) 步。

假设 \(B\) 走 \(h\) 步后停在了 \(x\),现在,我们只需要分析最劣的那种情况————“备选点”在 \(x\) 子树内,然后算出答案。

(为什么是最劣的?因为上面说了“备选点”不在 \(x\) 子树内的话,\(B\) 就会往最远点走,而 \(A\) 当然不想便宜 \(B\),所以肯定会堵住这条路,即在 \(x\) 子树内)

这时 \(B\) 要么朝着没有“备选点”的儿子走,要么往上走。考虑怎么快速计算。

首先 \(v\) 的最远点一定是树的直径端点之一,可以快速计算。将 \(v\) 的最远点当作根,可以用倍增快速将 \(v\) 跳到 \(x\)。接着 \(x\) 的父亲肯定不能走(因为是最远点,上面一定有“备选点”),只需要考虑 \(x\) 的子树就行了。

设 \(x\) 是从 \(y\) 跳上来的,那么第二种情况相当于求 \(y\) 子树内的最深叶子,可以快速维护。

至于第一种情况,没有“备选点”的儿子相当于其最深叶子深度 \(< d-h-1\),可以用 vector 或 set 记录 \(x\) 每个儿子子树的最深叶子深度,排序后二分即可。

时间复杂度 \(\mathcal O(n\log n)\)。

代码

#include<bits/stdc++.h>
using namespace std;
using namespace my_std;
ll n,q,head[100010],cnt=0,dep[100010],rt;
struct node{
	ll nxt,to;
}e[200020];
void add(ll u,ll v){
	e[++cnt].nxt=head[u];
	e[cnt].to=v;
	head[u]=cnt;
}
struct tree{
	vector<ll> vec[100010];
	ll rt,dep[100010],maxdep[100010],f[100010][22];
	void dfs(ll fa,ll u){
		dep[u]=dep[fa]+1;
		f[u][0]=fa;
		fr(i,1,18) f[u][i]=f[f[u][i-1]][i-1];
		go(u){
			ll v=e[i].to;
			if(v==fa) continue;
			dfs(u,v);
			maxdep[u]=max(maxdep[u],maxdep[v]+1);
			vec[u].push_back(maxdep[v]+1);
		}
		sort(vec[u].begin(),vec[u].end());
	}
	void init(ll RT){
		rt=RT;
		dfs(0,rt);
	}
	ll jump(ll x,ll t){
		pfr(i,18,0) if(t&(1ll<<i)) x=f[x][i];
		return x;
	}
	ll query(ll x,ll d){
		ll h=(d-1)/2,ans=0;
		if(h){
			x=jump(x,h-1);
			ans=max(ans,d-h+maxdep[x]+1);
			x=f[x][0];
		}
		ll tmp=lower_bound(vec[x].begin(),vec[x].end(),d-h)-vec[x].begin()-1;
		if(tmp>=0) ans=max(ans,d-h+vec[x][tmp]);
		else ans=max(ans,d-h);
		return ans;
	}
}t1,t2;
void dfs(ll fa,ll u){
	dep[u]=dep[fa]+1;
	if(dep[u]>dep[rt]) rt=u;
	go(u){
		ll v=e[i].to;
		if(v==fa) continue;
		dfs(u,v);
	}
}
int main(){
	n=read();
	q=read();
	fr(i,2,n){
		ll u=read(),v=read();
		add(u,v);
		add(v,u);
	}
	dfs(0,1);
	ll nrt=rt;
	rt=0; 
	t1.init(nrt);
	dfs(0,nrt);
	t2.init(rt);
	while(q--){
		ll v=read(),d=read();
		if(t1.dep[v]>=t2.dep[v]) writeln(t1.query(v,d));
		else writeln(t2.query(v,d));
	}
}

实际上本文有些地方不严谨,偏向感性(

主要是想了几天还是不会严谨证明,就摆烂了。有严谨证明的可以在下面回复,十分感谢!

标签:rt,Ptz2022,dep,题解,ll,dfs,fa,Kyoto,备选
From: https://www.cnblogs.com/AFewSuns/p/17081101.html

相关文章

  • i.MX6ULL - 问题解决:NFS挂载失败 - VFS: Unable to mount root fs on unknown-block(2
    i.IMX6ULL-问题解决:NFS挂载失败-VFS:Unabletomountrootfsonunknown-block(2,0)开发环境:移植的linux5.4.7.0ubuntu1804x64arm-linux-gnueabihf-gccv7.5NFS方式......
  • Qt | QListWidgetItem返回错误的背景颜色(始终返回颜色值为0)问题解决
    Qt|QListWidgetItem返回错误的背景颜色(始终返回颜色值为0)问题解决使用场景:程序使用QListWidget显示一个列表,这个列表具有点击选择和再次点击取消选择的功能,点击之后需要更......
  • SOJ1728 题解
    题意有一个长度为\(n\)的数列\(a_0,a_1,\dots,a_{n-1}\)以及一个长度为\(m\)的操作序列\((b_0,c_0),(b_1,c_1)\dots(b_{m-1},c_{m-1})\)。执行\(t\)次操作,第\(......
  • ARC 155 题解
    A目前见过的最阴间的A。寻找规律,发现最后的回文串一定是由若干个周期拼起来的。当周期长度为偶数时,\(S\)和\(S'\)可以各拿半个周期。于是kmp求出border,再判一下,但......
  • 题解 P5507 机关
    传送门毕设老师让我做MAPF,由于学了好多A*算法的变形,就过来做一做了。这题用的是EPEA*(EnhancedPartialExpansionA*)算法【分析】显然搜索能过,但是状态空间太大了......
  • docker “no space left on device”问题解决
    在​​Linux​​环境上使用docker执行命令时遇到了“nospaceleftondevice”可能是存储镜像的路径磁盘满了1、先使用dockerinfo查看docker的信息dockerinfo可以看到do......
  • ptz2023题解/训练记录 #1 Petrozavodsk Winter Camp 2023 day1 JAGain in Petrozavods
    ProblemA.Agriculture签到题,没看,被队友切了ProblemB.BlocksandExpressions签到题,没看,被队友切了ProblemC.ChangingtheSequences首先,建图吧。然后,二分图最......
  • 题解 【[USACO23JAN] Lights Off G】
    problem给两个长为\(n\)的0/1字符串\(S,T\),进行如下操作\(cnt\)次:自行选定\(0\leqx<n\),使得\(T_x\)异或一。将\(S\)异或上\(T\)。将\(T\)的最后一位......
  • 题解 【[USACO23JAN] Find and Replace G】
    problem有一个字符串\(S\),初始时为\(\tt'a'\),现在进行\(n\)次操作,第\(i\)次操作形如:将\(S\)中的所有的字符\(ch_i\)替换为字符串\(T_i\)。然后输出\(S[l......
  • 【题解】favorite school
    标准程序1:#include<bits/stdc++.h>usingnamespacestd;intt,del,cha,flag[4],check[4];strings;unordered_map<char,int>pos;intslove(intx,inty,intz,int......