树状数组POJ - 3321

看邝bin大佬题解写的。http://poj.org/problem?id=2481这是题

#include
#include
#include
#include
#define lowbit(x) x&(-x)
const int maxn = 100200;


using namespace std;

int n;
int a[maxn],pp[maxn];

struct node{
    int x;
    int y;
    int pos;
}e[maxn];

bool cmp(node a,node b){ 扔进树状数组里的必须是从小到大的数,这样才能用Sum统计,看他前面有多少已经出现的值。哎呀  感觉说不清楚,有问题的话可以私聊我。
    if(a.y != b.y)  return a.y > b.y;
    return a.x < b.x;
}

void Update(int x,int value){
    while(x <= n){
        pp[x] += value;
        x += lowbit(x);
    }
}

int Sum(int x){
    int sum = 0;
    while(x >= 1){
        sum += pp[x];
        x -= lowbit(x);
    }
    return sum;
}

int main(){
    while(~scanf("%d",&n) && n){
        memset(pp,0,sizeof(pp));
        memset(a,0,sizeof(a));
        int x,y;
        for(int k = 1 ; k <= n ; k++){
            scanf("%d%d",&e[k].x,&e[k].y);
            e[k].pos = k;
        }
        sort(e+1,e+n+1,cmp);
//        for(int i = 1 ; i <= n ; i++){
//            printf("%d %d %d\n",e[i].y,e[i].x,e[i].pos);
//        }
        a[e[1].pos] = 0;
        Update(e[1].x + 1,1);
        for(int i = 2 ; i <= n ; i++){
            if((e[i].x == e[i - 1].x) && (e[i].y == e[i - 1].y)){
                a[e[i].pos] = a[e[i - 1].pos];//判断是否是真子集
            }
            else{
                a[e[i].pos] = Sum(e[i].x + 1);
            }
            Update(e[i].x + 1,1);
        }
        for(int i = 1 ; i <= n ; i++){
            printf("%d%c",a[i],i == n?'\n':' ');
        }
    }
    return 0;
}
/*
3
4 5
4 6
3 6
*/

你可能感兴趣的:(树状数组POJ - 3321)