您的位置:首页 > 其它

poj 2481 Cows(树状数组)

2014-09-01 09:33 134 查看
题目链接:点击打开链接

题意:山坡上长满三叶草,给定一群牛和他们喜爱的范围【S,Ei】,如果一头牛的S小于等于另一头牛而E大于等于另一头牛的,且S和E不同时相等,那么这头牛就比另一头牛强壮。

可以先对E从大到小排序,这样保证遍历时后出现的牛的上界一定满足小于等于前面的,这样只需要判断他的下界满不满足就行,这就想到了用树状数组。

用树状数组c[i]保存到 i 前有多少牛的下界判断过了。

这样对每个牛先把他的下界加进去,再查有多少小于他的下界的牛,答案就是这个数-1(减他自己)

对于判断S和E不同时相等有一个好的办法,就是添加完后先判断当前区间是否和前一个区间完全相同,如果相同就直接让答案等于前一个区间的。因为区间完全相同的一定排在一起且答案相同,这样当第一个加进去的时候此时除他自己以外没有别的妞区间和他完全相同,按上面的算法得到正确的答案,后面每一个就复制他的答案即可。

本题范围是从零开始,直接输入0会在query时引起死循环,所以输入时全部+1

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define MAX 100010
using namespace std;
struct cow{
    int s,e,id;
    bool operator ==(cow obj){
        return s==obj.s&&e==obj.e;
    }
}a[MAX];
int res[MAX];
bool cmp(cow a,cow b){
    return a.e>b.e||(a.e==b.e&&a.s<b.s);
}
int c[MAX];
int N;
int lowbit(int n){
    return n&(-n);
}

void add(int n,int p){
    while(p<=MAX) {
        c[p]+=n;
        p+=lowbit(p);
    }
}

int query(int p){
    int res=0;
    while(p>0){
        res+=c[p];
        p-=lowbit(p);
    }
    return res;
}

int main(){
    while(~scanf("%d",&N)){
        memset(c,0,sizeof(c));
        if(!N) break;
        for(int i=1;i<=N;i++){
            scanf("%d%d",&a[i].s,&a[i].e);
            a[i].id=i;
        }
        sort(a+1,a+N+1,cmp);
        for(int i=1;i<=N;i++){
            add(1,a[i].s+1);
            if(a[i]==a[i-1]){
                res[a[i].id]=res[a[i-1].id];
            }
            else{
               res[a[i].id]=query(a[i].s+1)-1;
            }
        }
        for(int i=1;i<N;i++){
            printf("%d ",res[i]);
        }
        printf("%d\n",res
);
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: