hrbust 2132 哈理工oj 2132 数方格【二维树状数组】

数方格
Time Limit: 1000 MSMemory Limit: 32768 K
Total Submit: 15(12 users)Total Accepted: 9(9 users)Rating: Special Judge: No
Description

有一个S*S的方格,行和列都是从0S-1

有四种操作:      

操作

参数

含义

0

S

初始化表格,大小为S*S,所有单元格的值均为0。(此操作只出现一次且一定是第一条操作)

1

X Y A

将(X)单元格的值增加A

2

L B R T

询问矩形区域(x,y)内的值的输出答案,其中x,y满足L<= x <= R, B <= y <= T

3

结束,此操作只出现一次且一定是最后一条

范围限制:

方格大小

S*S

1 <= S <= 1024

任意时刻单元格的值V

V

0 <= V <= 32767

每次增加的值A

A

-23768 <= A <= 23767

输入的操作总数

M

3 <= M <= 60002

所有单元格值之和

T

T <= 230

Input

本题只有一组测试数据。

第一行为操作0

最后一行为操作3

中间操作数不多于60000

Output

输入输出格式请参考DescriptionSample

Sample Output

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

Hint

3

4

Source
2014暑假集训练习赛(7月30日)

思路:

对应每一个操作都有对应的分步处理。

对应update操作:

        if(op==1)
        {
            int x,y,val;
            scanf("%d%d%d",&x,&y,&val);
            update(x+1,y+1,val);//对应点的入图。
        }
对应query操作:
            int x1,y1,x2,y2;
            scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
            int c=getsum(x1,y1);
            int d=getsum(x2+1,y2+1);
            int e=getsum(x1,y2+1);
            int f=getsum(x2+1,y1);
            printf("%d\n",d-e-f+c);

完整的AC代码:

#include<stdio.h>
#include<string.h>
using namespace std;
int m;
int a[1030][1030];
int lowbit(int x)
{
    return x&(-x);
}
void update(int x,int y,int d)
{
    int temp=y;
    while(x<=m)
    {
        y=temp;
        while(y<=m)
        {
            a[x][y]+=d;
            y=y+lowbit(y);
        }
        x=x+lowbit(x);

    }

}
int getsum(int x,int y)
{
    int sum=0;
    int temp=y;
    while(x>0)
    {
        y=temp;
        while(y>0)
        {
            sum=sum+a[x][y];
            y=y-lowbit(y);
        }
        x=x-lowbit(x);
    }
    return sum;

}
int main()
{
    int op;
    while(~scanf("%d",&op))
    {
        if(op==3)break;
        if(op==0)
        {
            memset(a,0,sizeof(a));
            scanf("%d",&m);
        }
        if(op==1)
        {
            int x,y,val;
            scanf("%d%d%d",&x,&y,&val);
            update(x+1,y+1,val);
        }
        if(op==2)
        {
            int x1,y1,x2,y2;
            scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
            int c=getsum(x1,y1);
            int d=getsum(x2+1,y2+1);
            int e=getsum(x1,y2+1);
            int f=getsum(x2+1,y1);
            printf("%d\n",d-e-f+c);
        }
    }
}












评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值