Cows POJ - 2481 (树状数组)

Cows

 题目链接:POJ - 2481 

题意:John家里有好多奶牛,所有奶牛都在同一条直线上活动,第i个奶牛活动范围是[Si, Ei],对于两头奶牛i, j来说如果Si<=Sj&&Ei>=Ej&&Ej-Sj<Ei-Si 则奶牛i比奶牛j强壮,也就是说如果j的活动范围在i的活动范围内且不重合的话,奶牛i就比奶牛j强壮;对每个奶牛,求出比他强壮的奶牛的数量;

思路:再来整理一下题意:[Si, Ei]不就是一条线段嘛!也就是说当线段j是线段i的真子区间时i比j强壮;

先把E由大到小排序然后x由小到大排序,然后插入树状数组即可;

#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int maxn=100010;
int tr[maxn], ans[maxn];
struct point{
	int x, y, id;
	bool operator < (const point &p)const{
		if(y!=p.y) return y>p.y;
		return x<p.x;
	}
}p[maxn];
int lowbit(int x){
	return x&(-x);
}
void updata(int x){
	while(x<maxn){
		tr[x]++;
		x+=lowbit(x);
	}
}
int getsum(int x){
	int s=0;
	while(x>0){
		s+=tr[x];
		x-=lowbit(x);
	}
	return s;
}
int main(){
	int n;
	while(scanf("%d", &n), n){
		int x, y;
		memset(tr, 0, sizeof(tr));
		for(int i=1; i<=n; i++){
			scanf("%d%d", &p[i].x, &p[i].y);
			p[i].x++;
			p[i].y++;
			p[i].id=i;
		}
		p[0].x=-1, p[0].y=-1;
		sort(p+1, p+n+1);
		memset(ans, 0, sizeof(ans));
		for(int i=1; i<=n; i++){
			if(p[i].x==p[i-1].x&&p[i].y==p[i-1].y) ans[p[i].id]=ans[p[i-1].id];
			else ans[p[i].id]=getsum(p[i].x);
			updata(p[i].x);
		}
		for(int i=1; i<=n; i++){
			printf("%d%c", ans[i], i==n?'\n':' ');
		}
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/sirius_han/article/details/81122156
今日推荐