QOJ.ac

QOJ

Type: Editorial

Status: Open

Posted by: louyuxuan

Posted at:

Last updated:

Back to Problem

New Editorial for Problem #22859

考虑按照编号从小到大依次求出每个点结尾的最长路 $f_u$。设处理到 $v$ 时所有 $u<v$ 的 $f_u$ 都已经知道。

当 $v$ 是黑点的时候,将所有白点 $u$ 按照 $f_u$ 降序排序并且二分第一个和 $v$ 有边的 $u$,二分然后每次询问一个前缀即可。询问次数不超过 $\log n$。

当 $v$ 是白点的时候,不能直接单独处理,一个想法是整体处理所有 $v$,由于有先后顺序的,考虑 cdq 分治。先把分治中心左侧的所有 $v$ 都处理,然后把左边的黑点 $u$ 按照 $f$ 降序排序,依次考虑每个 $u$,询问右侧白点集合,如果存在一条 $u$ 到右侧白点 $v$ 的边,二分找到后删除这个 $v$ 然后继续查找。

这样看上去的操作次数是 $\mathcal{O}(n\log^2n)$ 的。但是一脸常数小的样子,严谨分析一下:只有一个黑点的区间只会进行 $\le\log n$ 次的二分,每个黑点 $u$ 在每一层询问至多返回一次 $0$,对于层内返回 $1$ 的询问,把 $v$ 的二进制写出来,从下往上第 $k$ 层中 $v$ 在右半区间当且仅当二进制下第 $k$ 位为 $1$,而这一层找到 $v$ 的代价至多 $k$,所以一个白点 $v$ 的代价至多为 $\sum\limits_{k=0}^8(k+1)v_2(k)$,其中 $v_2(k)$ 表示 $v$ 二进制下第 $k$ 位的值。那么整体询问次数不超过 $\sum\limits_{s=0}^{511}\max(18,\sum\limits_{k=0}^8v_2(s))=12348<15000$,所以是正确的。

Comments

No comments yet.