【2018icpc Regional Dhaka G】Techland 题解

题目大意

  有一棵 $n$ 个点的树,点编号 $1,\cdots,n$。有 $Q$ 次操作,操作有三种类型:
  $1\ X\ L\ R$:公司 $X$ 在编号属于 $[L,R]$ 的点上各开一家商店。如果该公司曾经有过商店,则它以前的商店全部清除,只算这次的。
  $2\ X$:公司 $X$ 的商店全部清除。
  $3\ C\ M\ P_1\ P_2\ …\ P_M$:有个人在 $C$ 号点,他指定了他喜欢的公司为 $P_1,\cdots,P_M$,你要找到一个离 $C$ 最近的点,使得这个点有他喜欢的公司开的商店。求这个距离。

  单组数据:$n \leq 50000,\ Q \leq 10^5,\ \sum m \leq 10^5$
  10 组数据共 10s。

题解

对了..上次那个 G 题,我后来想了想发现是个点分水题.
——liyang21

  由于 $\sum m \leq 10^5$,只需要对于每个 $P_i$,求 $C$ 点到相应的 $[L_i,R_i]$ 这些点的最短距离就好了。

  你想,要是每个点 $x$ 有一棵线段树,记录着 $x$ 到所有点的最短距离,那就好了,就可以对于每个询问直接区间查询 $[L_i,R_i]$ 的最小值了。

  但这样太大了。想办法以时间换空间,我查询多一些东西,让这个线段树总量少些。

  由于最近点是经典点分题,于是想到了点分

  考虑点分树,对于每个点,只记录它的子树上的所有点到它的最短距离。你可以给点重新编号,或者用主席树,使得这个线段树总大小为 $O(n \log n)$。
  这样一来,点 $x$ 到终点 $z$ 的路径就被分为了两部分,第一部分是 $x$ 到它点分树上的祖先 $y$,第二部分是 $y$ 到 $z$。
  因此查询的话,就从点分树的根一直查到那个点。比如上面说的我查询点 $x$,现在考虑它点分树上的祖先 $y$,那么就是 $dis_{x,y}+\min\{dis_{y,z}|z\in[L_i,R_i]\}$,这就是线段树区间查询了。点分树树高为 $\log n$,线段树查询有一个 $\log n$,因此复杂度为 $O(m \log^2 n)$。