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]
还有需要注意的是:
因getsun求得是【1,x】而不是【x,maxn)所以,转化为之前的个数减去小于他的个数。
为什么是小于他的个数,即为什么是id-1?
因为他左边界已经不同,即使右边界相同,力量也会比他大!!
题目大意:
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;
}
相关文章推荐
- POJ 2481 Cows 树状数组
- poj 2481 Cows(树状数组 | 线段树)
- POJ 2481 Cows (树状数组)
- poj 2481 - Cows(树状数组)
- poj 2481 Cows 【树状数组】
- POJ 2481 Cows(树状数组)
- POJ 2481 Cows && POJ 2352 Stars(树状数组妙用)
- POJ 2481 Cows 树状数组
- poj 2481 Cows(树状数组)题目有陷阱,转换后与stars类似
- [树状数组] poj 2481 Cows
- POJ 2481 Cows && POJ 2352 Stars(树状数组妙用)
- POJ 2481 COWS(树状数组)
- POJ 2481 Cows(树状数组)
- POJ 2481 Cows 简单树状数组区间覆盖
- POJ-2481 Cows 树状数组
- POJ 2481 Cows【树状数组】
- POJ - 2481 Cows解题报告(树状数组 相同点重复计数处理)
- POJ 2481 Cows(树状数组)
- poj 2481 Cows--树状数组 + 区间真子集个数
- POJ 2481 Cows (树状数组)