BISHI112 【模板】二维前缀和¶
中等通过率 43.63%python3样例通过牛客 AC
讲解章节:前缀和与差分
一句话
q 次子矩阵求和查询。
解题思路¶
这题考什么¶
二维前缀和的容斥公式。令
递推:P[i][j] = P[i-1][j] + P[i][j-1] - P[i-1][j-1] + a[i][j] 查询:S(x1,y1,x2,y2) = P[x2][y2] - P[x1-1][y2] - P[x2][y1-1] + P[x1-1][y1-1] 「减两次多减了左上角那块,要加回来」是容斥的全部内容。
数据规模与复杂度¶
n, m <= 1e3(矩阵最多 1e6 个数),q <= 1e5。 预处理 O(nm),每次查询 O(1)。若每次查询暴力累加,最坏 1e5 * 1e6 = 1e11,必挂。
Python 实现要点¶
- 用一维扁平数组存 P,宽度 W = m+1,下标 i*W+j。 二维嵌套 list 每次要走两级索引,1e5 次查询 * 4 次访问的差距不小;
- 每一行的构建拆成两步纯 C 层操作: 行内前缀和 -> itertools.accumulate 与上一行逐项相加 -> map(add, 上一行, 本行行内前缀和) 这样 1e6 个格子的预处理不写一个 Python 层循环体;
- 读入 1e6 + 4e5 个 token,必须 sys.stdin.buffer.read().split()。
坑在哪¶
- 行/列下标从 1 开始,P 要多开一圈 0(第 0 行、第 0 列全 0), 否则 x1-1 = 0 时会越界或取到错误的值;
- 扁平化后行宽是 W = m+1(含第 0 列),(i, j) 的下标是 i*W + j。 行宽写成 m 就会让相邻两行错位一格,症状是越靠下的行越离谱;
- a_{i,j} 可以为负,前缀和不单调,但容斥公式与单调性无关;
- 矩阵和最大 1e6 * 1e9 = 1e15,C++ 必须 long long;Python 无忧;
- 输出 1e5 行,用 "\n".join 一次性写出,逐行 print 会被 IO 拖死。
参考实现¶
[:octicons-arrow-left-16: BISHI111](BISHI111.md) [BISHI113 :octicons-arrow-right-16:](BISHI113.md)