其实是场上的想到的做法,但是当时被卡 corner case 了 QaQ。
注意到,我们其实可以 \(O(1)\) 次 query
求出 \(x\) 和 \(y\) 的距离。具体地,我们再找三个点,现在有 \(5\) 个点,\(10\) 个距离,而我们又可以 query
\(10\) 次,正好可以解出两两距离。这里如果 \(n\le 4\) 特判手玩就好。
然后考虑动态加点,维护直径。如果只维护直径的两个端点 \(x,y\),求距离其实不是很方便。(好像可以 \(10\) 次加三个点,应该就是 Subtask 10?)
考虑存三个点 \(x,y,z\),并且记录 \(\operatorname{dis}(x,y)\),\(\operatorname{dis}(y,z)\) 和 \(\operatorname{dis}(z,x)\)。其中较大的 \(\operatorname{dis}\) 我们现在考虑加入 \(i\)。
令 \(x\),\(y\),\(z\) 的中间点为 \(p\),不妨设加入的 \(i\) 是从 \(x-p\) 的链中分叉出来的,分叉点是 \(t\)。
那么我们查询一下 \((x,y,i)\),\((y,z,i)\),\((z,x,i)\),然后我们又已知 \(x\),\(y\),\(z\) 两两的距离,其实我们可以解出所有的距离。然后就可以更新直径了。
问题是我们并不知道 \(i\) 是从那一条链分叉出去,这个也是可以处理的。可以发现,如果是从 \(x-p\) 分叉出去的,那么 \(\dfrac{\operatorname{query}(x,y,i)}{2}-\operatorname{dis}(x,y)=\dfrac{\operatorname{query}(x,z,i)}{2}-\operatorname{dis}(x,z)=e\),并且 \(\dfrac{\operatorname{query}(y,z,i)}{2}-\operatorname{dis}(y,z)\neq e\)。
于是我们只要根据上面的条件就可以确定 \(i\) 从哪条链分出去。于是就可以 \(3\) 次加入一个点了。总次数 \(10+3(n-5)=3n-5\)。
https://qoj.ac/submission/877333