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 }
today:
你从不讲真心话
叫我如何大冒险
寂寞拥抱寂寞
难道就不寂寞