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;
}

 

转载于:https://www.cnblogs.com/-ifrush/p/10682553.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值