好的,我将这道题整理为清晰的题面格式,并补充样例解释、数据范围与时空限制:
题目描述
这是一道模板题。
给出一个 n×m 的零矩阵 A,你需要完成如下操作:
1 x y k:表示元素 Ax,y 自增 k(即 Ax,y←Ax,y+k);
2 a b c d:表示询问左上角为 (a,b),右下角为 (c,d) 的子矩阵内所有数的和(即 ∑i=ac∑j=bdAi,j)。
输入格式
第一行有两个正整数 n,m,表示矩阵的行数和列数。
接下来若干行,每行一个操作,直到文件结束(EOF)。
操作格式:
输出格式
对于每个操作 2,输出一行一个整数,表示该子矩阵的元素和。
样例
样例输入
2 2
1 1 1 3
1 2 2 4
2 1 1 2 2
样例输出
7
样例说明
初始矩阵:
[0000]
操作1:1 1 1 3 → A1,1=3
矩阵变为:
[3000]
操作2:1 2 2 4 → A2,2=4
矩阵变为:
[3004]
操作3:2 1 1 2 2 → 询问左上角 (1,1) 到右下角 (2,2) 的子矩阵和 =3+0+0+4=7。
数据范围
- 对于 10% 的数据,n=1(一维情况);
- 对于另 10% 的数据,m=1(一维情况);
- 对于全部数据:
- 1≤n,m≤212=4096
- 1≤x,a,c≤n
- 1≤y,b,d≤m
- ∣k∣≤105
- 操作数目不超过 3×105
- 保证询问的子矩阵存在(即 a≤c,b≤d)
时空限制
- 时间:1000 ms
- 内存:524288 KB(512 MB)
提示
此题为 二维树状数组 的模板题。
二维树状数组:
- 支持单点更新(Ax,y←Ax,y+k);
- 支持二维前缀和查询(∑i=1x∑j=1yAi,j);
- 通过二维前缀和差分可以得到任意子矩阵和。
子矩阵和公式:
设 sum(x,y)=∑i=1x∑j=1yAi,j,则:
$$\sum_{i=a}^{c} \sum_{j=b}^{d} A_{i,j} = sum(c,d) - sum(a-1,d) - sum(c,b-1) + sum(a-1,b-1)$$
二维树状数组操作:
- 单点更新
add(x, y, k):对所有 i≥x,j≥y 的 tree[i][j] 加 k;
- 前缀和查询
sum(x, y):返回 ∑i=1x∑j=1yAi,j。
复杂度:
- 单点更新:O(logn⋅logm)
- 子矩阵查询:O(logn⋅logm)
注意:
- 由于 n,m≤4096,二维数组
tree[4097][4097] 占用内存约 $4097\times 4097 \times 4\text{ bytes} \approx 67\text{ MB}$,加上其他变量在 512 MB 内存内可行;
- 输入直到 EOF,注意判断读入结束;
- k 可能为负数,使用
int 或 long long 存储(前缀和可能超出 int 范围,建议用 long long)。