poj1195——Mobile phones

题目大意:有一个边长为S的正方形区域,每个小方块内都有一个基站和很多手机,一个小方块内的活跃手机数量不固定,因为手机可以移动到其他小方块内或者可以开机关机。根据给出的一系列变化情况,输出查询的指定区域内的活跃手机个数。区域内手机总共最多2^30个。小方块内手机个数0 <= V <= 32767。

输入:(四种情况,输入行数范围3 <= U <= 60002)

           0  S(初始化S*S的每个小方块都为0,1 * 1 <= S * S <= 1024 * 1024)

           1  X  Y  A(小方块(X,Y)内的活跃手机个数加A, -32768 <= A <= 32767,X,Y的范围是0~S-1)

           2  L  B  R  T(查询以(L,B)为左上角,(R,T)为右下角的区域内活跃手机的个数)

           3(代表输入结束)

输出:对每个查询输出活跃手机个数(各占一行)

分析:二维树状数组。注意树状数组下标从1起,所以输入的坐标都要加1。二维和一维的同理更新和求和,只是稍作修改。

代码:转载自http://blog.csdn.net/lin375691011/article/details/21247409

#include <stdio.h>  
#include <string.h>  
int num[1050][1050],s;  
int lowbit(int x)  
{  
    return x&(-x);  
}  
void  add(int x,int y,int val)  
{  
    for(int i=x;i<=s;i+=lowbit(i))  
    {  
        for(int j=y;j<=s;j+=lowbit(j))  
        {  
            num[i][j]+=val;//num[][]相当于一维中的C[]数组,不过二维是在两个方向
        }  
    }  
}  
int query(int x,int y)  
{  
    int ans=0;  
    for(int i=x;i>0;i-=lowbit(i))  
    {  
        for(int j=y;j>0;j-=lowbit(j))  
        {  
            ans+=num[i][j];  
        }  
    }  
    return ans;  
}  
int main()  
{  
    int t,q,x,y,sum,l,r,a;  
    scanf("%d%d",&t,&s);  
    memset(num,0,sizeof(num));  
    while(scanf("%d",&q),q<3)  
    {  
        if(q==1)  
        {  
            scanf("%d%d%d",&x,&y,&a);  
            x++;  
            y++;  
            add(x,y,a);  
        }  
        else if(q==2)  
        {  
            scanf("%d%d%d%d",&x,&y,&l,&r);  
            x++;  
            y++;  
            l++;  
            r++;  
            printf("%d\n",query(l,r)-query(l,y-1)-query(x-1,r)+query(x-1,y-1));  
        }  
    }  
    return 0;  
} 


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值