题面
【题目描述】
假设 T a m p e r e Tampere Tampere区域的第四代手机基地站运行如下。该区域被划分为一些正方形(方阵)。这些正方形构成一个 S S S╳ S S S的矩阵,矩阵行和列的编号从 0 0 0到 S − 1 S-1 S−1。每个正方形包含一个基地站。由于一个手机可能从一个正方形移动到另一个正方形,或者手机可能开机或关机,所以,在一个正方形内正在使用的手机数目是随时变化的。有时,每个基地站需要将正在使用的手机数的变化用矩阵的行和列报告给主基地站。
请你写一个程序,接收这些报告并回答有关任一个长方形区域内当前正在使用的手机总数的查询。
【输入】
输入是从标准输入读入整数,对查询的回答是把一个整数写到标准输出。输入格式如下。每个输入占用一行,每行由一个标志数和一些参数构成,标志数和这些参数的格式见下表。
标志数 | 参 数 | 意 义 |
---|---|---|
0 | S | 用全零来初始化矩阵,大小为 S´S. 该标志数仅仅给出一次,并将是第一个标志数。 |
1 | X Y A | 将A的值加到矩阵表方阵(X,Y)当前正在使用的手机数目中。A 可正可负。 |
2 | L B R T | 在方阵(X,Y)中查询当前正在使用的手机数的总和,其中 L ≤ X ≤ R , B ≤ Y ≤ T L \leq X \leq R,B \leq Y \leq T L≤X≤R,B≤Y≤T |
3 | 结束程序 | 该标志数仅仅给出一次并将是最后一个标志数。 |
所有数值将始终在范围内,因而不需要检查。特别是,当 A A A为负时,可以假定它不会把正方形内的数目减到 0 0 0以下。范围的序号从 0 0 0开始。例如,对于一个 4 4 4* 4 4 4的表, X X X和 Y Y Y的变化范围为 0 ≤ X ≤ 3 , 0 ≤ Y ≤ 3 0\leq X\leq 3, 0\leq Y\leq 3 0≤X≤3,0≤Y≤3。
对于一个标志数非(不是) 2 2 2的行,你的程序不应回答任何内容。如果标志数是 2 2 2,你的程序应当将答案以一个整数的形式写到标准输出来回答查询。
【输出】
对于每一个标志数为 2 2 2的,输出结果。
【样例输入】
0 4
1 1 2 3
2 0 0 2 2
3
【样例输出】
3
【数据范围】
矩阵表大小 | S S S✖ S S S | 1 ✖ 1 ≤ S ✖ S ≤ 1024 ✖ 1024 1✖1 \leq S✖S \leq 1024✖1024 1✖1≤S✖S≤1024✖1024 |
---|---|---|
任意时间的单元值 | V V V | 0 ≤ V ≤ 2 15 – 1 0 \leq V \leq 2^{15} –1 0≤V≤215–1 ( = 32767 =32767 =32767) |
更新量 | A A A | − 2 15 ≤ A ≤ 2 15 – 1 -2^{15} \leq A \leq 2^{15}–1 −215≤A≤215–1 ( = 32767 = 32767 =32767) |
输入中标志数的数目 | U U U | 3 ≤ U ≤ 60002 3 \leq U \leq 60002 3≤U≤60002 |
整个矩阵表中手机数的最大值 | M M M | M = 2 30 M= 2^{30 } M=230 |
在 20 20 20个输入中, 16 16 16个输入(矩阵表)的大小最多是 512 ✖ 512 512✖512 512✖512。
算法分析
二维树状数组模板题目
本题对矩阵进行操作,对矩阵进行询问,方法与一维树状数组类似,才有二维树状数组。
参考程序
#include<bits/stdc++.h>
using namespace std;
int n;
long long c[N][N];
long long ans;
int lowbit(int x)
{
return x&(-x);
}
void update(int x,int y,long long k) //区间更新
{
int i=x;
while(i<=N)
{
int j=y;
while(j<=N)
{
c[i][j]+=k;
j+=lowbit(j);
}
i+=lowbit(i);
}
}
long long sum(int x,int y) //区间求和,矩阵(1,1)~(x,y)的和
{
long long ans=0;
int i=x;
while(i>0)
{
int j=y;
while(j>0)
{
ans+=c[i][j];
j-=lowbit(j);
}
i-=lowbit(i);
}
return ans;
}
int main()
{
int x,y,x1,y1,m;
long long k;
while(1)
{
scanf("%d",&m);
if(m==0) {
scanf("%d",&x);memset(c,0,sizeof(c));}
if(m==1)
{
scanf("%d%d%lld",&x,&y,&k);
update(x+1,y+1,k);
}
if(m==2)
{
scanf("%d%d%d%d",&x,&y,&x1,&y1);
x++;y++;x1++;y1++;
ans=sum(x1,y1)-sum(x-1,y1)-sum(x1,y-1)+sum(x-1,y-1); //二维前缀和
printf("%lld\n",ans);
}
if(m==3) break;
}
return 0;
}
今天的文章二维树状数组区间查询区间修改_二维数组a[10…20][5…10]分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/81883.html