zoukankan      html  css  js  c++  java
  • hdu--2642--二维BIT

    BIT---Binary Index Tree. 树状数组...关于它的入门介绍 网上有很多博客 我这边不具体展开写了 就想提一些..

    lowbit(x)是真正的这个树状数组的核心 都是靠它来传递的

    网上 那张经典的图 有必要好好模拟计算一下 一维是二维的基础。。

    使用的好 它能解决很多线段树可以解决的问题..当然有些问题 它是不能解决的..

    这题 应该算让我们认识下 二维树状数组的吧 关于它的资料 网上不是很多 小白书上 似乎只是一笔带过 我忘了...

    二维树状数组一般是用来计算子矩阵的和 可以看成在一个二维坐标系上 有X轴 Y轴

    代码 其实很简单 就是多增加一个for而已 但是需要好好地理解它 因为三维 甚至更高维度的也会出现..

    我想 二维树状数组 最让自己难计算的就是子矩阵之和了  假如给你两点(x1,y1)  (x2,y2)让你求得它的矩阵每个格子相加总的和是多少?

    我画张图 来有助理解---这就是接下去用代码来完成的

    这里 假设 x2>=x1   y2>=y1 当然题目有时候会故意出数据是x1>x2  y2>y1的 我们就要将它们进行交换  这样的目的是为了计算出和的时候可以正确表示

    在一维中 getSum(x)就是前X个元素的和 那么二维就是getSum(x,y)前X行前J列的元素的和.

    因为x1,y1是要取到的 所以需要-1 那么 其实我的图 画的是有问题的...理解就好 艹了=-=

    所以getSum(x2,y2)=S1+S2+S3+S4    getSum(x1-1,y1-1)=S3  getSum(x2,y1-1)=S4+S3 getSum(x1-1,y2)=S2+S3

    let see code

    这边 需要将它给你的坐标分别+1  是因为 题目的数据范围从0开始

    但是 lowbit(0)=0 这样会造成死循环的=-=

     1 #include <iostream>
     2 #include <cstring>
     3 #include <algorithm>
     4 using namespace std;
     5 
     6 const int size = 1010;
     7 int tree[size+5][size+5];
     8 bool flag[size+5][size+5];
     9 
    10 int lowbit( int x )
    11 {
    12     return x&-x;
    13 }
    14 
    15 void update( int x , int y , int num )
    16 {
    17     for( int i = x ; i<=size ; i+=lowbit(i) )
    18     {
    19         for( int j = y ; j<=size ; j+=lowbit(j) )
    20         {
    21             tree[i][j] += num;
    22             //cout << tree[i][j] << endl;
    23         }
    24     }
    25 }
    26 
    27 int getSum( int x , int y )
    28 {
    29     int sum = 0;
    30     for( int i = x ; i ; i-=lowbit(i) )
    31     { 
    32         for( int j = y ; j ; j-=lowbit(j))
    33         {
    34             sum += tree[i][j];
    35         }
    36     }
    37     return sum;
    38 }
    39 
    40 int main()
    41 {
    42     cin.sync_with_stdio(false);
    43     char ch;
    44     int m , x , y , x1 , y1 , x2 , y2 , ans;
    45     cin >> m;
    46     memset( tree , 0 , sizeof(tree) );
    47     memset( flag , false , sizeof(flag) );
    48     while(m--)
    49     {
    50         cin >> ch;
    51         if( ch=='Q' )
    52         {
    53             cin >> x1 >> x2 >> y1 >> y2;
    54             ++ x1;
    55             ++ y1;
    56             ++ x2;
    57             ++ y2;
    58             if(x1>x2)
    59                 swap(x1,x2);
    60             if(y1>y2)
    61                 swap(y1,y2);
    62             ans = getSum(x2,y2) + getSum(x1-1,y1-1) - getSum(x2,y1-1) - getSum(x1-1,y2);
    63             cout << ans << endl;
    64         }
    65         else 
    66         {
    67             cin >> x >> y;
    68             ++ x;
    69             ++ y;
    70             if( ch=='B' )
    71             {
    72                 if(!flag[x][y])
    73                 {
    74                     flag[x][y] = true;
    75                     update( x , y , 1 );
    76                 }
    77             }
    78             else
    79             {
    80                 if( flag[x][y] )
    81                 {
    82                     flag[x][y] = false;
    83                     update( x , y , -1 );
    84                 }
    85             }
    86         }
    87     }
    88     return 0;
    89 }
    View Code

    today:

      你从不讲真心话

      叫我如何大冒险

      

      寂寞拥抱寂寞

      难道就不寂寞

    just follow your heart
  • 相关阅读:
    析构函数可以内联吗(可以,但不建议)
    auto_ptr
    Oracle Enterprise Linux 6.0配置本地yum
    标准C++输入输出和字符串类学习小程序集锦
    [转载]解决mysql“Access denied for user 'root'@'localhost'”
    [Linux网络编程学习笔记]套接字地址结构
    javascript基础
    java学习笔记14动态代理
    2013面试总结_01
    jquery实现复选框checkbox全选(完善)
  • 原文地址:https://www.cnblogs.com/radical/p/3933975.html
Copyright © 2011-2022 走看看