Loading

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\) 位置前面

posted @ 2026-09-29 21:29  tai_chi  阅读(2)  评论(0)    收藏  举报