您的位置:首页 > 其它

poj 2481 Cows(树状数组)

2017-07-19 15:47 309 查看
题目链接: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;

思路:

[b]一:总体的思路[/b]

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

[b]二:牛的排序[/b]



struct node
{
int s,e;
int number;
bool operator <(const node &tmp)const
{
//按照左边界的顺序排序  当左边界相同时  力量大的在前  即右边界大的在前
if(s!=tmp.s)
return s<tmp.s;
else
return 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; else return 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;
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: