树状数组是一种类似于线段树的数据结构;
它各节点之间的移动方式基于二进制的进位;
每个下标存储值是下标 最低位1后面所跟0的个数的二倍的 该点之前的数据之和;
如 : 10100 存了四个元素的和,是a[10100] a[10011] a[10010] a[10001]
移动到父节点(存元素和更多的节点)的方法是进位,即 x+lowbit(x) :10100 +100 =11000;
移动到辖域前一个节点的方法是退位,即 x-lowbit(x): 10100 - 100 =10000; 10000存储了a[10001]前的4*2位元素;
题目:以y升序的x升序输入n个点的坐标,求 满足:左下方分别有0 , 1 ,2 ... n-1个点 的点的个数;
用树状数组存对应x坐标已有的点的个数,因为是按特定顺序输入的,输入时可以直接统计:
#include <cstdio> #include <cstring> using namespace std; int c[32000+10]; int a[15000+10]; int lowbit( int x){ return x & (-x); } void updata( int x ,int v){ while ( x<= 32005){ c[x] += v; x+=lowbit( x); } } int getsum( int x){ int res = 0; while( x>0){ res += c[x]; x-=lowbit( x);; } return res; } int main( ){ int n; int x ,y; while ( ~scanf("%d" ,&n)){ memset( c ,0 ,sizeof( c)); memset( a ,0 ,sizeof( a)); for( int i=0 ;i<n ;i++){ scanf( "%d%d" ,&x ,&y); a[ getsum( x+1)]++; updata( x+1 , 1); } for( int i=0 ;i<n ;i++){ printf("%d\n" ,a[i]); } } return 0; }