POJ 1195 Mobile phones【二维树状数组】

本文介绍了一种使用二维树状数组解决矩形区域内求和问题的方法,并提供了详细的代码实现。通过对最大矩形区域进行操作并调整相邻部分,可以有效地更新和查询数值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

POJ 1195 Mobile phones【二维树状数组】

  77人阅读  评论(0)  收藏  举报

       简单的二维树状数组,求一个矩形区域内的和,因为要随时增减,而且可能减的数比原来都大,所以需要保留原来的数组。
在求矩形区域和的时候,只要用最大的矩形减去两个小的,再加上那个多减的最小的,就OK了.

 

[cpp]  view plain copy
  1. #include<iostream>  
  2. #define M 1300  
  3. int c[M][M],a[M][M],n;  
  4. int lowbit(int t){  
  5.         return t&(t^(t-1));  
  6. }  
  7. int sum(int p,int q){  
  8.         int x=p,y,total=0;  
  9.         while(x>0){  
  10.                 y=q;  
  11.                 while(y>0){  
  12.                         total+=c[x][y];  
  13.                         y-=lowbit(y);  
  14.                 }  
  15.                 x-=lowbit(x);  
  16.         }  
  17.         return total;  
  18.  }  
  19. void modify(int p,int q,int key){  
  20.         int x=p,y;  
  21.         while(x<=n){  
  22.                 y=q;  
  23.                 while(y<=n){  
  24.                         c[x][y]+=key;  
  25.                         y+=lowbit(y);  
  26.                 }  
  27.                 x+=lowbit(x);  
  28.         }  
  29.  }  
  30.  int main()  
  31.  {  
  32.         int i,j,k,jj,kk,m,order,ans;  
  33.         scanf("%d%d",&i,&n);  
  34.         memset(c,0,sizeof(c));  
  35.         memset(a,0,sizeof(a));  
  36.         while(scanf("%d",&order)!=EOF){  
  37.                 if(order==3) break;  
  38.                 else if(order==1){  
  39.                         scanf("%d%d%d",&j,&k,&m);  
  40.                         ++j;  ++k;  
  41.                         if(m<0&&m*(-1)>a[j][k]){  
  42.                                 m=(-1)*a[j][k];  
  43.                                 modify(j,k,m);  
  44.                                 a[j][k]=0;  
  45.                         }  
  46.                         else{  
  47.                                 modify(j,k,m);  
  48.                                 a[j][k]+=m;  
  49.                         }  
  50.                 }  
  51.                 else if(order==2){  
  52.                         scanf("%d%d%d%d",&j,&jj,&k,&kk);  
  53.                         ++j; ++jj; ++k; ++kk;  
  54.                         //printf("%d ",sum(n,n));  
  55.                         ans=sum(k,kk)+sum(j-1,jj-1)-sum(k,jj-1)-sum(j-1,kk);  
  56.                         printf("%d/n",ans);  
  57.                 }  
  58.         }  
  59. }  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值