zoukankan      html  css  js  c++  java
  • 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;

    }

  • 相关阅读:
    为知笔记使用备注
    困惑激发的正能量
    再多坚持一会,相信自己就好!
    看博文《前路漫漫,何为终点?》的一点小感想
    前端的杂谈
    JS 客户端检测
    DOM
    JavaScript & XML
    我所认识的XPath
    Javascript 面向对象编程
  • 原文地址:https://www.cnblogs.com/yejinru/p/2412359.html
Copyright © 2011-2022 走看看