P3960
树状数组,重点在于奇怪的拆分维护。
题意
有一个 \(n \times m\) 的矩阵,其中的元素从左上到右下从 \(1\) 到 \(n \times m\) 编号。\(q\) 次询问,每次给出一个坐标 \((x,y)\),执行下述操作:
- 将当前矩阵中坐标为 \((x,y)\) 的元素删除;
- 将其右边的元素(\((x,y+1)\) 到 \((x,m)\))向左移动一格;
- 最后一列空位下面的元素(\((x+1,m)\) 到 \((n,m)\))向上移动一格;
- 原来在 \((x,y)\) 的元素补到 \((n,m)\) 位置。
对每次询问回答删除的元素的值。
\(n,m,q \le 3 \times 10^5\)。
分析
注意到最后一列是特殊的,我们分别考虑最后一列,和去除最后一个元素的每一行的情况。每个操作等价于单点删除并查询、末尾补上一个数。这可以使用树状数组维护。

由于末尾的插入,一个数组最多会涉及 \(n-1+q\) 或 \(m+q\) 个数,我们设一个长度为 \(n-1+q\) 或 \(m+q\) 的树状数组,初始全为 \(1\)。单点删除就把对应位置置为 \(0\)。这时树状数组的 query(p) 前缀和操作就代表了 \(p\) 位置前面

浙公网安备 33010602011771号