UOJ Logo DaiRuiChen007的博客

博客

标签
暂无

#841. 龙门探宝 k=3 的做法

2024-03-18 09:41:03 By DaiRuiChen007

1 为根,求出每个点的深度 di=dist(1,i),记 i 左边第一个比 i 深的点是 pre(i),右边第一个比 i 深的点是 suf(i)

Li=dist(i,suf(i))dsuf(i),Ri=dist(pre(i),i)dpre(i),求出如上信息的总代价为 3n

那么记 [l,r] 中最深的点是 u,那么 f(l,r)=du+max(LlLu1,Ru+1Rr),证明如下:

首先我们可以通过调整法证明区间直径一定经过 u,否则把其中一个端点换成 u 肯定不劣。

考虑每个 Lx 对答案的贡献:

  • suf(x)=u,那么 Lx=dx2dLCA(x,u),那么 Lx+du=dist(u,x)
  • suf(suf(x))=u,那么只要考虑 Lx>Lsuf(x) 的情形,否则 x 必定无贡献,由于 dxdsuf(x),因此 dLCA(x,suf(x))<dLCA(suf(x),u),所以 LCA(x,suf(x))LCA(suf(x),u) 的祖先,因此 LCA(x,suf(x))=LCA(x,u)

所以只要 Lx>Lsuf(x)LCA(x,suf(x))=LCA(x,suf(suf(x))),数学归纳法可以证明最大的 x 满足 LCA(x,suf(x))=LCA(x,u)

证毕。

那么原问题就转化成了一个数据结构问题,自然的想法是考虑对 d 建立大根笛卡尔树。

设当前节点为 p,子树区间为 [l,r]dp 的贡献就是 (rp+1)×(pl+1)1

我们只要求 lippjrmax(LiLp1,Rp+1Rj)

假如 p 是区间中点,那么这是经典的,枚举 i,双指针求 j 为最后一个满足 max(Rp+1Rj)max(LiLp1)j

那么 max(LiLp1) 的贡献就是 jp+1,而 j<jrmax(Rp+1Rj) 可以简单后缀和。

但是此时 p 不一定是区间中点,如果处理复杂度是 O(rl) 的话会退化到 O(n2),但是如果可以做到 O(min(pl,rp)) 的话,相当于每次遍历笛卡尔树上的轻子树,复杂度显然是 O(nlogn)

不妨假设 plrp,我们依然枚举每个 i,那么 j 可以二分求出,max(LiLp1) 贡献依然是简单计算的。

j<jrmax(Rp+1Rj) 可以拆成 p<jrmax(Rp+1Rj)p<jjmax(Rp+1Rj)

那么问题就变成了 O(nlogn) 次询问 fr(x,y)=xiymax(RxRi)

离线这些问题后可以扫描线,单调栈+区修区查树状数组维护前缀最大值,可以 O(nlog2n) 求出答案。

询问次数 3n,时间复杂度 O(nlog2n)

Submission Link

共 1 篇博客