Stars HDU - 1541(树状数组

 

树状数组是一种类似于线段树的数据结构;

它各节点之间的移动方式基于二进制的进位;

每个下标存储值是下标 最低位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;
}
posted @ 2019-04-10 11:50  易如鱼  阅读(234)  评论(0编辑  收藏  举报