Description
Input
Output
Sample Input
0 4 1 1 2 3 2 0 0 2 2 1 1 1 2 1 1 2 -1 2 1 1 2 3 3
Sample Output
3 4
在S*S的数组中,某些区域的数值是时常变化的,编写程序计算出任意时刻,某一区域的数值和。
输入:
每行一个或多个数字,如果某一行的第一个数字是3时,结束操作;如果某一行的第一个数字是0,那么接下来只有一个数,是S;如果某一行的第一个数字是1时,接下来有三个数,分别是X,Y,A,表示在X,Y对应的点加上A(注意:X,Y可以为0);如果某一行的第一个数字是2时,接下来有四个数,分别是L,B,R,T,表示(L,B)与(R,T)所围区域的和。
解题思路:
利用二维树状数组求解,详细介绍请仔细查看代码及注释。
代码如下:
#include <stdio.h> #include <string.h> int S,a[1025][1025]; int lowbit(int x) { return x&(-x); } //更新二维树状数组,对(x,y)所在元素加num void updata(int x,int y,int num) { int i,j; for(i=x;i<=S;i+=lowbit(i)) { for(j=y;j<=S;j+=lowbit(j)) { a[i][j]+=num; } } } //求和((1,1)到(x,y)区域的所有元素的和) int SUM(int x,int y) { int i,j,sum=0; for(i=x;i>0;i-=lowbit(i)) { for(j=y;j>0;j-=lowbit(j)) { sum+=a[i][j]; } } return sum; } int main() { int t; while(scanf("%d",&t)&&t!=3) { if(t==0) { scanf("%d",&S); memset(a,0,sizeof(a)); } if(t==1) { int X,Y,A; scanf("%d%d%d",&X,&Y,&A); updata(X+1,Y+1,A); } if(t==2) { int L,B,R,T; scanf("%d%d%d%d",&L,&B,&R,&T); printf("%d\n",SUM(L,B)+SUM(R+1,T+1)-SUM(L,T+1)-SUM(R+1,B)); } } return 0; }
F - Mobile phones,布布扣,bubuko.com
原文地址:http://blog.csdn.net/yanghuaqings/article/details/38333481