【题解】Solution Set - NOIP2024集训Day3 权值线段树、动态开点、主席树

【题解】Solution Set - NOIP2024集训Day3 权值线段树、动态开点、主席树

「JSOI2018」列队

一个结论:所有的人都按顺序依次去她该去的位置,一定是不劣的。bf

现在式子变成了:(\(a_i\) 排序

\[Ans=\sum_{i=1}^{r-l+1}|a_i-(k+i-1)| \]

先建一颗主席树,维护 \(a_i\)

显然 \(a_i,k+i\) 都单增,而且 \(a_i\) 的变化量一定是不小于 \(k+i\) 的,所以可以二分中间的断点来消除绝对值。

时间复杂度:\(O(n\log n\log V)\)


然后发现 T 了。

改成线段树上二分就好了。

注意一下,与直接二分位置不同,线段树上二分要二分值域,然后再推出位置。


「BZOJ十连测」可持久化串串

首先,最短循环节 = \(n\) - 最长的 border。

如果每次暴力跑这条链的话,时间复杂度应该是所有链的长度之和,

Solution1 - border 性质

考虑让每次跳 \(nxt\) 不超过 \(\log \text {链长}\) 次。设当前点为 \(i\)

对于每一次 \(s[nxt_j+1]\ne s[i]\) 分讨一下:

  1. \(nxt_j\le \left\lfloor\frac j2\right\rfloor\):直接跳,\(j\) 的规模减小一半。
  2. \(nxt_j> \left\lfloor\frac j2\right\rfloor\):一定存在一个 \(j-nxt_j\) 的循环节,而对于每一个循环节的后一个元素一定 \(\ne s[i]\),所以我们可以一次性跳到第一个循环节的末尾,即 \(j\bmod (j-nxt_j)\),因为 \(j-nxt_j\le \left\lfloor\frac j2\right\rfloor\),所以 \(j\) 的规模也减小一半。

每次倍增判断 \(s[nxt_j+1]=s[i]\),总时间复杂度为 \(O(n\log^2n)\)


Solution2 - 可持久化

考虑维护从任意点作为最后元素,在加入任意一个新元素 \(i\) 时,\(j\)\(nxt_{fa}\) 最后跳到的 \(nxt\)​(其实就是直接维护所有可能出现的询问。

先从 \(nxt_i\) 继承,然后更新一下 \(ch\) 的位置就好了。

时间复杂度:\(O(n\log n)\)


今天的题都是自己做出来的,可喜可贺😉

posted @ 2024-08-09 08:11  CloudWings  阅读(16)  评论(0编辑  收藏  举报