poj 1195 mobile phones 二维树状数组

这道题就是一道比较裸的二维树状数组,刚练完一维后,可以来做一做。

我觉得一维树状数组思路是很清晰的,而二维树状数组比较抽象,所以必须透彻理解一维树状数组后,才能稍微明白二维的。

在纸上先画个二维图,然后边画边想便理解,有点像二重积分,二重循环。。。

这道题题意是说:大小为S*S的区域内,每个小格中初始化时有0个手机,然后通过不同的操作,可以像每个小格中添加手机,最后查询某个矩形区域内手机的总个数。

附上代码:

#include <iostream>
using namespace std;
int a[1030][1030]; //二维树状数组
int s;                  //区域的边长
int lowbit(int t)
{
 return t&(-t);   
}
void insert(int x,int y,int d) //;两个循环维护数组区间
{
  while(x<=s)
  {
    int y1=y;
    while(y1<=s)
    {
      a[x][y1]+=d;
      y1+=lowbit(y1);  
    }
    x+=lowbit(x);
  }
}
long long  getsum(int x,int y)  //求取一个区域内的手机数量
{
  long long  sum=0;
  while(x>0)
  {
    int y1=y;
    while(y1>0)
    {
     sum+=a[x][y1];
     y1-=lowbit(y1);    
    }
    x-=lowbit(x);
  }
 return sum;
}
int main()
{
 int x1,x2,y1,y2,flag;
 double d; 
 while(cin>>flag)
 {
   if(flag==3)break;
   else if(flag==0)
   {
    cin>>s;
    
    for(int i=1;i<=s;i++)     //初始化,使得最开始每个小格内的手机数量为0
      for(int j=1;j<=s;j++)
      {
        a[i][j]=0;
        a[j][i]=0;  
      }
   }
   else if(flag==1)
   {
     cin>>x1>>y1>>d;
     x1++;y1++;  //之所以要++是因为树状数组不能从0开始计数
     insert(x1,y1,d);  
   }
  else if(flag==2)
  {
     cin>>x1>>y1>>x2>>y2;
     x1++;y1++;x2++;y2++;
     long long  sum=0;
     sum=getsum(x2,y2)-getsum(x1-1,y2)-getsum(x2,y1-1)+getsum(x1-1,y1-1); //画画图便于理解
     printf("%lld\n",sum);
  }
 }
 return 0;   
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值