题解 宝石
题意简述
(n) 个点的树,每个点点权 ([0,c]) , (q) 次询问每次给出 (s,t) 表示询问由 (s) 到 (t) 的这条路径上面的点权组成的序列中最长的且满足 (p_i=i) 的子序列 (p) 的长度。
(1le n,qle 2 imes 10^5,1le cle 5 imes 10^4) 。
部分分表格:
测试点编号 | $n,qle $ | 特殊限制 |
---|---|---|
(1sim 2) | (10) | 无 |
(3sim 5) | (1000) | 无 |
(6sim 10) | (2 imes 10^5) | (cle 300) |
(11sim 14) | (2 imes 10^5) | 树的第 (i) 条边连接 (i) 和 (i+1) |
(15sim 20) | (2 imes 10^5) | 无 |
题目分析
测试点 (1sim 2)
每次询问暴力提取出 (s) 到 (t) 的链,暴力枚举子序列检查,时间复杂度 (mathcal O(q2^nn)) 。
测试点 (3sim 5)
提取出链后可以从 (1) 到 (c) 找每一个数,然后找到序列中最靠前的满足条件的位置,这样贪心显然没有问题,时间复杂度 (mathcal O(qn)) 。
测试点 (6sim 10)
测试点 (11sim 14)
序列 (A) 末尾加上序列 (B) 后的答案只和序列 (A) 的答案和 (B) 有关,想到可以对每个线段树上面的序列处理某个数为答案时加上这个序列后答案为多少,一个序列需要处理的答案数量是小于序列长度的,所以复杂度就是对的。直接用 map 实现处理答案时间复杂度为 (mathcal O((n+q)log_2^2n)) , hash 的话 (mathcal O((n+q)log_2n)) 。
另一种思路是离线分治,时间复杂度 (mathcal O((n+q)log_2n)) 。
测试点 (15sim 20)
树剖或者 LCT 加序列第一种思路的做法就可以做到 (mathcal O((n+q)log_2n)) 或者 (mathcal O((n+q)log_2^2n)) 或者 (mathcal O((n+q)log_2^3n)) 。
离线点分治加序列第二种思路的做法可以做到 (mathcal O((n+q)log_2n)) 。
另外的做法大都是对于每次询问 (s,t) 找到 lca 然后按从下到上和从上到下处理,从下到上倍增等很好处理,从上到下可以离线一遍 dfs 加并查集,也可以二分后转化成类似从下到上处理。