poj 2481 Cows(树状数组)

来源:互联网 发布:安全网络教育平台下载 编辑:程序博客网 时间:2024/05/22 19:27

题目链接:http://poj.org/problem?id=2481

题目大意:

1 题目给定n头牛所在的区间,然后问每头牛都有几头牛比它强壮
2 根据题目如果牛i的区间是[Si , Ei],牛j的区间是[Sj , Ej]那么牛i要比牛j强壮的话那么就有Si <= Sj && Ei >= Ej && Si-Ei != Sj-Ej;

思路:

一:总体的思路

先对每个牛排序,然后对每头牛查找比他的力量大的牛的个数

二:牛的排序

struct node{int s,e;int number;bool operator <(const node &tmp)const{//按照左边界的顺序排序  当左边界相同时  力量大的在前  即右边界大的在前if(s!=tmp.s)return s<tmp.s;elsereturn e>tmp.e;}bool operator ==(const node &tmp)const{return s==tmp.s&&e==tmp.e;}}nodes[MAXN];
因为我们之后是对每头牛查找力量比他的牛,所以先按照左边界的顺序排序  ,即保证之前牛的左边界一定比他小,即在他之后的牛一定不可能力量比他的,比他力量大的牛只可能在之前,所以当左边界相同时 ,也需要力量大的在前  ,即右边界大的在前.


还有需要注意的是:

ans[nodes[i].number]+=i-getSum(id-1);

因getsun求得是【1,x】而不是【x,maxn)所以,转化为之前的个数减去小于他的个数。

为什么是小于他的个数,即为什么是id-1?

因为他左边界已经不同,即使右边界相同,力量也会比他大!!

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;const int MAXN =100010;struct node{int s,e;int number;bool operator <(const node &tmp)const{//按照左边界的顺序排序  当左边界相同时  力量大的在前  即右边界大的在前if(s!=tmp.s)return s<tmp.s;elsereturn e>tmp.e;}bool operator ==(const node &tmp)const{return s==tmp.s&&e==tmp.e;}}nodes[MAXN];int n;int ans[MAXN];int treenum[MAXN];int lowbit(int x){    return x&(-x);}int getSum(int x){//一维    int sum = 0;    while(x){//将以x为根节点的数 相当于求其叶节点的和  但其非叶节点等于其两个子节点的和        sum += treenum[x];        x -= lowbit(x);    }    return sum;}void add(int x , int val){//一维    while(x < MAXN){//相当于一个树  他将其自己以及他的父节点一路向上都加val         treenum[x] += val;         x += lowbit(x);    }}void solve(){memset(ans,0,sizeof ans);memset(treenum,0,sizeof treenum);sort(nodes,nodes+n);for(int i=0;i<n;i++){int id=nodes[i].e;if(i&&nodes[i]==nodes[i-1])ans[nodes[i].number]=ans[nodes[i-1].number];else{ans[nodes[i].number]+=i-getSum(id-1);//为什么要id-1? 因为他是之前的个数减去小于他的个数,即求大于等于他的个数// 他左边界已经不同 右边界可以相同}add(id,1);} printf("%d" , ans[0]);    for(int i = 1 ; i < n ; i++)       printf(" %d" , ans[i]);    printf("\n");}int main(){while(~scanf("%d",&n)&&n){for(int i=0;i<n;i++){scanf("%d%d",&nodes[i].s,&nodes[i].e);nodes[i].number=i;}solve();}    return 0;}