链接:http://ybt.ssoier.cn:8088/problem_show.php?pid=1540
【题目描述】
这是一道模板题。
给出一个 n×m 的零矩阵 A,你需要完成如下操作:
1 x y k:表示元素 Ax,y自增 k;
2 a b c d:表示询问左上角为 (a,b),右下角为 (c,d) 的子矩阵内所有数的和。
【输入】
输入的第一行有两个正整数 n,m;
接下来若干行,每行一个操作,直到文件结束。
【输出】
对于每个 2 操作,输出一个整数,表示对于这个操作的回答。
【输入样例】
2 2
1 1 1 3
1 2 2 4
2 1 1 2 2
【输出样例】
7
【提示】
数据范围与提示:
对于 10% 的数据,n=1;
对于另 10% 的数据,m=1;
对于全部数据,1≤n,m≤212,1≤x,a,c≤n,1≤y,b,d≤m,∣k∣≤105 ,保证操作数目不超过 3×105 ,且询问的子矩阵存在。
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int N=4100;
int n,m,x,y,z,t,p;
int c[N][N];
int read();
int lowbit(int x)
{
return (-x)&x;
}
void update(int x,int y,int z){
for(int i=x;i<=n;i+=lowbit(i)){
for(int j=y;j<=m;j+=lowbit(j))
c[i][j]+=z;
}
}
long long query(int x,int y)
{
long long res=0;
for(int i=x;i>0;i-=lowbit(i)){
for(int j=y;j>0;j-=lowbit(j))
res+=c[i][j];
}
return res;
}
int main()
{
n=read();m=read();
while(scanf("%d",&t)==1)
{
if(t==3) break;
x=read();y=read();z=read();
if(t==1)
{
update(x,y,z);
}
else{
p=read();
printf("%lld\n",query(z,p)-query(x-1,p)-query(z,y-1)+query(x-1,y-1));
}
}
return 0;
}
int read()
{
int s=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-') f=-f;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
s=(s<<3)+(s<<1)+ch-'0';
ch=getchar();
}
return s*f;
}