POJ 1195 Mobile phones

树状数组第一题,上来就是二维树状数组,这是逼着我用树状数组做啊,二维线段树不会写啊~~


题目大意:

给定矩阵大小,可以更新矩阵中的某些数,要求输出某个范围内的所有数之和。


解题思路:

二维树状数组可解。

一维树状数组讲解:点击打开

二维树状数组只是在更新方式上稍作改变。

在数组长度为n的树状数组中:

寻找下一个需要添加的数的下标:

int lowbit(int x)
{
    return x&(-x);
}


一维树状数组更新是这样的:

void add(int x,int val)
{
    for(;x<=n;x+=lowbit(x))
    {
        num[x]+=val;
    }
}

二维树状数组更新是这样的:

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;
        }
    }
}


一维树状数组查询是这样的:

int query(int x)
{
    int ans=0;
    for(;x>0;x-=lowbit(x))
    {
        ans+=c[i];
    }
    return ans;
}

查询的是1到x的数总和。


二维树状数组查询是这样的

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;
}

查询的是(1,1)到(x,y)的数的总和。


下面是代码:

#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;
        }
    }
}
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;
}



  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值