CF1588F Jumping Through the Array

题意

有一个长度为 nn 的数组 aa 和一个长度为 nn 的排列 pp,对于每一个 ii 有一条有向边 (i,pi)(i, p_i). 有 qq 次如下三种操作:

  • 1 l r,询问 lirai\sum\limits_{l\le i\le r}a_i
  • 2 v x,将所有从 vv 出发能到达的节点的编号在 aa 上对应的值加上 xx
  • 3 x y,交换 pxp_xpyp_y

n,q2×105n,q\le2\times 10^5

题解

考虑对操作序列分块,每块结束后暴力重构

由于 pp 始终是一个排列,在任一时刻所有边构成的图是若干个环

注意到每次操作3会更改两个点的出边,在同一个操作序列的块中的这样的点将图分为若干色块,每个色块在这个操作序列的块中都不会发生改变

示意图

由于关键点只有 O(n)\mathcal{O}(\sqrt{n}) 个,色块也只有 O(n)\mathcal{O}(\sqrt{n})

操作2就是在所有能到达的色块上打一个加法标记

考虑操作1
对于每一个询问我们将其差分为两个前缀和,也就是一个块内一共询问 O(n)\mathcal{O}(\sqrt{n}) 个前缀和
由于一共只有 O(n)\mathcal{O}(\sqrt{n}) 种颜色和 O(n)\mathcal{O}(\sqrt{n}) 个有用的前缀和,可以 Θ(n)\Theta(n) 预处理出在所有用到的前缀和中每种颜色的点的个数

重构的时候,每个数加上它所在色块的加法标记

每块预处理的时间复杂度为 Θ(nn)\Theta(n\sqrt{n}),所有修改与询问的时间复杂度为 O(nn)\mathcal{O}(n\sqrt{n}),因此总时间复杂度为 Θ(nn)\Theta(n\sqrt{n})

代码 codeforces submission 144997997

CF1588F Jumping Through the Array

https://gzezfisher.top/cf1588f/

作者

Fisher Cai

发布于

2022-02-03

更新于

2025-07-22

许可协议

评论

Your browser is out-of-date!

Update your browser to view this website correctly.&npsb;Update my browser now

×