PKUWC2025 D2T1

其实是场上的想到的做法,但是当时被卡 corner case 了 QaQ。

注意到,我们其实可以 O(1)query 求出 xy 的距离。具体地,我们再找三个点,现在有 5 个点,10 个距离,而我们又可以 query 10 次,正好可以解出两两距离。这里如果 n4 特判手玩就好。

然后考虑动态加点,维护直径。如果只维护直径的两个端点 x,y,求距离其实不是很方便。(好像可以 10 次加三个点,应该就是 Subtask 10?)

考虑存三个点 x,y,z,并且记录 dis(x,y)dis(y,z)dis(z,x)。其中较大的 dis 就是直径。我们现在考虑加入 i

xyz 的中间点为 p,不妨设加入的 i 是从 xp 的链中分叉出来的,分叉点是 t

那么我们查询一下 (x,y,i)(y,z,i)(z,x,i),然后我们又已知 xyz 两两的距离,其实我们可以解出所有的距离。然后就可以更新直径了。

问题是我们并不知道 i 是从哪一条链分叉出去,这个也是可以处理的。可以发现,如果是从 xp 分叉出去的,那么 query(x,y,i)2dis(x,y)=query(x,z,i)2dis(x,z)=e,并且 query(y,z,i)2dis(y,z)e

于是我们只要根据上面的条件就可以确定 i 从哪条链分出去。于是就可以 3 次加入一个点了。总次数 10+3(n5)=3n5

https://qoj.ac/submission/877333

Upd:

有一个少一些观察的做法。

我们还是动态加点,同时只维护直径的两端点以及距离。

每次加入三个点,那么我们可以用 10query 求出这五个点两两之间距离。

但是我们已经知道了直径长度,相当于少一个未知数,那么我们也可以少一次 query。于是就可以 9 次加入 3 个点。总次数还是 3n 带一些常数的。

posted @   CJzdc  阅读(15)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示