CF1588F 题解

题意

传送门

你有个长度为 \(n\) 的数组 \(a\) 和一个长度为 \(n\) 的排列 \(p\),对于每一个 \(i\) 有一有向边 \((i,p_i)\)

有如下三种操作:

  • 1 l r 询问 \(\sum_{i=l}^r a_i\)

  • 2 v x 将所有 \(v\) 能到达的节点所对应编号的值加 \(x\)

  • 3 x y 交换 \(p_x\)\(p_y\)

对于每一 \(1\) 操作输出结果。

\(1\le n,q\le 2\times10^5\)

题解

发现操作 \(3\) 难以处理。先考虑没有 \(3\) 的情况。容易得出一个 \(O(n\sqrt n)\) 的算法:将操作分为 \(\sqrt n\) 块,对于每个操作 \(2\) 给对应环打上标记,对于操作 \(1\) 分为两部分算:同一块内的,考虑所有有标记的环,统计环上有几个点 \(\in[l,r]\),乘上标记;不同块的,在每块结束时 \(O(n)\) 统计一下即可。

再看有 \(3\) 的情况。此时环会合并或分裂。但当环的变化次数比较少时,环上很大一部分也是可以使用标记的。将所有 \(3\) 操作的 \(x,y\) 称为关键点,则关键点可以将所有环(参与合并或分裂的环)分为 \(O(\sqrt n)\) 条链。于是给链打标记,用类似上面的方法做。

分析一下复杂度。操作 \(2\) 的复杂度为 \(O(\sqrt n)\),操作 \(3\)\(O(1)\),操作 \(1\)\(O(\sqrt n\log n)\)。瓶颈在于二分。先将 \([l,r]\) 分为 \([1,l)\)\([1,r]\),因为一条链上 \([1,r]\) 的个数不会随标记改变,于是可以预处理。这样就规避了二分。复杂度 \(O(n\sqrt n)\)

posted @ 2023-03-19 16:57  realFish  阅读(76)  评论(0)    收藏  举报