题解:P12001 在小小的奶龙山里面挖呀挖呀挖
奶浓~~~
题意概述
题目给出一个含有 \(n\) 个休息点的树,每个点有一个数值 \(a_i\)。数值的每个质因子代表一个参与该点建设的“公司”。对于每条从 \(u\) 到 \(v\) 的路径,我们需要统计路径上所有休息点所涉及的不同公司的数量,即不同质因子的个数。
Solution
思维难度不大,简单糊一下。
使用筛法预先求出较小的质数。对于每个点的数值 \(a_i\) 分解质因数(注意同一质因子重复只记一次),并将质因子映射为一个编号,方便后续统计。
然后对树做一次 DFS,记录每个节点的进入时间 \(st\) 和退出时间 \(en\)。这样,每个节点在 DFS 欧拉序中会出现两次,构造出一维数组。预处理出每个节点的祖先信息,便于快速求出任意两点的 LCA。
每条查询路径从 \(u\) 到 \(v\),可以通过 LCA 分解成两个区间,如果 \(u\) 是 LCA,则区间就是 \([st[u], st[v]]\),否则需要额外考虑 LCA 节点。将所有查询离线排序,按照莫队的思想在欧拉序上维护当前区间,并利用区间增删操作更新答案。每次添加或删除一个节点时,更新该节点对应的质因子出现次数,从而判断某个公司是否第一次出现或最后一次消失,从而维护当前区间中质因子的个数。
如果查询路径的 LCA 不在构造的欧拉区间中,需要额外单独处理 LCA 节点,将其质因子计入答案后再恢复现场。
时间复杂度 \(O((n+q) \sqrt{n})\),可以被接受。