欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【2018icpc Dhaka G】Techland 题解

程序员文章站 2022-05-21 23:30:31
...

题目大意

  有一棵 nn 个点的树,点编号 11~nn。有 QQ 次操作,操作有三种类型:
  1 X L R1~X~L~R:公司 XX 在编号属于 [L,R][L,R] 的点上各开一家商店。如果该公司曾经有过商店,则它以前的商店全部清除,只算这次的。
  2 X2~X:公司 XX 的商店全部清除。
  3 C M P1 P2 ... PM3~C~M~P_1~P_2~...~P_M:有个人在 CC 号点,他指定了他喜欢的公司为 P1P_1~PMP_M,你要找到一个离 CC 最近的点,使得这个点有他喜欢的公司开的商店。求这个距离。

  单组数据:n50000, Q105, m105n \leq 50000,~Q \leq 10^5,~\sum m \leq 10^5
  10 组数据共 10s。

\\
\\
\\

题解

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

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

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

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

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

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

代码

\\待填坑