树状数组 POJ 2481 Cows


#include <iostream>
#include <cstdio>
#include <cstring>
#include <climits>
#include <vector>
#include <algorithm>
using namespace std;

#define SIZE 10005

int max_n = INT_MIN;

struct Node{
    
    Node():left( 0 ), right( 0 ), ID( 0 ){}
    
    int left;
    int right;
    int ID;
    
};


Node arr[SIZE];
int level[SIZE];
int countNum[SIZE];


int cmp ( const Node& a, const Node& b ){
    
    if( a.right == b.right ) 
        return a.left < b.left;
        
    return a.right > b.right;
    
}


int lowBit( int index ){
    return index & ( - index );
}


void update( int index, const int& val ){
    
    while( index < max_n + 1 ){
        
        countNum[index] += val;
        index           += lowBit( index );
        
    }
    
}


int getSum( int index ){
    
    int sum = 0;
    
    while( index >= 1 ){
        
        sum   += countNum[index];
        index -= lowBit( index );
        
    }
    
    return sum;
    
}


int main(){
    
    while( true ){
        
        memset( level, 0, sizeof(level) );
        int nCase;
        
        scanf( "%d", &nCase );
        
        vector< Node > arr( nCase + 1 );
        
        if( nCase == 0 ) 
            break;
            
        for( int i = 0; i < nCase; ++i ){
            
            int x, y;
            
            scanf( "%d%d", &x, &y );
            
            if( max_n < y ) 
                max_n = y;
                
            x++;
            y++;
            arr[i].left  = x;
            arr[i].right = y;
            arr[i].ID    = i;
            
        }
        
        sort( arr.begin(), arr.end(), cmp );
        
        for( int i = 0; i < nCase; ++i ){
            
            if( arr[i].left == arr[i - 1].left && arr[i].right == arr[i - 1].right )
                level[arr[i].ID] = level[arr[i - 1].ID];
            else
                level[arr[i].ID] = getSum( arr[i].left );
        
            update( arr[i].left, 1 );
            
        }
        
        for( int i = 0; i < nCase; ++i ) 
            printf( "%d ", level[i] );
            
        cout << endl;
        
    }
    
    return 0;
    
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值