hoj 1640 Mobile phones //poj 1195 Mobile phones 二维树状数组

/*

(x1,y2)   ____________    (x2,y2)

        |                      |

        |                      |

        |                      |

        |____________|

(x1,y1)                  (x2,y1)

 

在上面的矩形中,本题用树状数组来计算的,所以sum(x2,y2)计算的是它的左下方所有的

手机用户数,但是它多算了sum(x2,y1)以下的以及sum(x1,y2)以下的,若减掉即

ans = sum(x2,y2) - sum(x2,y1) -sum(x1,y2)的话,又减多了sum(x1,y1)部分,那只好加

上这一部分了。

 

另外,在update(),sum()时,无非算多了一维,很容易理解的,具体看代码,新学到了

      i -= lowbit(i)   ==      i = i&(i-1)

      i += lowbit(i)   ==      i = (i|(i-1))+1

输入的数据大时速度快很多,比如这题未改前我的代码在hoj上要1.39s,改完后要1.24s

 

*/

#include <iostream>

#include <cstdio>

using namespace std;

const int X = 1026;

int c[X][X],x,y,n,a,q,row,col;

/*int lowbit(int xx)

{

   return xx & -xx;

}*/

int sum(int i,int j)

{

   int temp,ans = 0;

   while(i>0)

   {

      temp = j;

      while(temp>0)

      {

         ans += c[i][temp];

         //temp -= lowbit(temp);

         temp = temp&(temp-1);

      }

      //i -= lowbit(i);

      i = i&(i-1);

   }

   return ans;

}

void update(int i,int j,int num)

{

   int temp;

   while(i<=row)

   {

      temp = j;

      while(temp<=col)

      {

         c[i][temp] += num;

         //temp += lowbit(temp);

         temp = (temp|(temp-1))+1;

      }

      //i += lowbit(i);

      i = (i|(i-1))+1;

   }

}

int main()

{

   freopen("sum.in","r",stdin);

   freopen("sum.out","w",stdout);

   int x1,x2,y1,y2;

   while(scanf("%d",&q)!=EOF)     //多case输入

   {

      if(!q)                //指令为0时,重新载入矩形大小,数组c[][]清零

      {

         scanf("%d",&n);

         row = col = n;

         for(int i=0;i<=n;i++)

            for(int j=0;j<=n;j++)

                c[i][j] = 0;

      }

      else if(q==1)      //指令为1时,在点(x,y)加上新的数,即update(x,y,num)

      {

         scanf("%d%d%d",&x,&y,&a);

         x++;        //给x,y增加一,以免为0时出现死循环

         y++;

         update(x,y,a);

      }

      else if(q==2)      //指令为2时,计算并输出矩形(x1,y1) (x2,y2)上所有的手机数量(大概意思)

      {

         scanf("%d%d%d%d",&x1,&y1,&x2,&y2);

         x2++;

         y2++;

         printf("%d\n",sum(x2,y2)+sum(x1,y1)-sum(x1,y2)-sum(x2,y1));

      }

   }

   return 0;

}

原文地址:https://www.cnblogs.com/yejinru/p/2412359.html