考虑一类经典的问题,形如有置换 \(x\leftarrow F(x)\),满足在一个值 \(B\) 次过后有 \(x=F(x)\)。
比较常见的是对序列维护区间置换,区间半群(或更弱)和。
例如 P4145 花神游历各国,其中 \(F(x)=\lfloor\sqrt x\rfloor\),\(B=\log \log V\),我们可以用势能线段树维护。
在线段树上每个点记录是否有数满足 \(x\neq F(x)\),然后每次修改我们暴力查找,不难分析出复杂度是 \(n\log n\log\log V\) 的。
但事实上这类问题是可以不依赖势能,并且可以可持久化的。
我们考虑维护一个区间的和为 \(s\),但这样不方便修改,于是我们考虑维护长为 \(B+1\) 的数组,分别为区间整体进行 \(i\in[0,B]\) 次置换过后的和。
不难发现我们合并就是两个数组每个位置对应相加,整体置换就是数组整体平移。
缺陷是我们的空间代价变为了原来的 \(B\) 倍。由于在大多数情况下,我们单次的查询都不弱于 \(O(B)\),于是我们可以考虑按 \(B\) 为长度底层分块,这样时间复杂度无太大变化,并且空间变为线性。
进一步的,我们可以可持久化,甚至可以用 WBLT 维护区间复制,平移。
example : https://www.luogu.com.cn/problem/P8524