挤奶牛Crowded Cows 洛谷p3088

题目描述

Farmer John's N cows (1 <= N <= 50,000) are grazing along a one-dimensional fence. Cow i is standing at location x(i) and has height h(i) (1 <= x(i),h(i) <= 1,000,000,000).

A cow feels "crowded" if there is another cow at least twice her height within distance D on her left, and also another cow at least twice her height within distance D on her right (1 <= D <= 1,000,000,000). Since crowded cows produce less milk, Farmer John would like to count the number of such cows. Please help him.

FJ有N(1 <= N <= 50,000)头奶牛沿着一维的栅栏吃草,第i头奶牛在目标点x(i) ,它的身高是 h(i) (1 <=x(i),h(i) <= 1,000,000,000)。

当一头奶牛左边D距离内而且右边D距离内有身高至少是它的两倍的奶牛,t (1 <= D <= 1,000,000,000),它就会觉得拥挤。

请计算觉得拥挤的奶牛的数量。

输入输出格式

输入格式:

 

* Line 1: Two integers, N and D.

* Lines 2..1+N: Line i+1 contains the integers x(i) and h(i). The locations of all N cows are distinct.

 

输出格式:

 

* Line 1: The number of crowded cows.

 

输入输出样例

输入样例#1: 复制

6 4 
10 3 
6 2 
5 3 
9 7 
3 6 
11 2 

输出样例#1: 复制

2 

说明

There are 6 cows, with a distance threshold of 4 for feeling crowded. Cow #1 lives at position x=10 and has height h=3, and so on.

The cows at positions x=5 and x=6 are both crowded.

 

#include
#define f(i,l,r) for(i=(l);i<=(r);i++)
using namespace std;
const int MAXN=50005;
int n,D;
int tree[MAXN<<2];
int ans;
struct Node{
	int x,h,l,r;
	bool operator < (const Node& tmp)const{
		return x>1;
	build(x<<1,l,mid);
	build(x<<1|1,mid+1,r);
	pushup(x);
}
inline void query(int x,int l,int r,int sj,int tj)
{
	if(sj<=l&&r<=tj){
		ans=max(ans,tree[x]);
		return;
	}
	int mid=l+r>>1;
	if(mid>=sj) query(x<<1,l,mid,sj,tj);
	if(mid+1<=tj) query(x<<1|1,mid+1,r,sj,tj);
}
int main()
{
	ios::sync_with_stdio(false);
	int i,j,pos;
	int res=0;
	cin>>n>>D;
	f(i,1,n){
		cin>>a[i].x>>a[i].h;
	}
	sort(a+1,a+1+n);
	f(i,1,n){
		Node tmp;
		tmp.x=a[i].x-D;
		pos=lower_bound(a+1,a+1+n,tmp,cmp)-a;
		a[i].l=pos;
		tmp.x=a[i].x+D;
		pos=lower_bound(a+1,a+1+n,tmp,cmp)-a;
		if(a[pos].x>a[i].x+D) pos--;
		a[i].r=pos;
	}
	build(1,1,n);
	f(i,2,n-1){
		ans=0;
		query(1,1,n,a[i].l,i);
		if(ans=a[i].h+a[i].h) res++;
	}
	cout<

 

#include
#define f(i,l,r) for(i=(l);i<=(r);i++)
#define ff(i,r,l) for(i=(r);i>=(l);i--)
using namespace std;
const int MAXN=50005;
struct Node{
	int x,h,l=0,r=0;
	bool operator < (const Node& tmp)const{
		return x q;
int main()
{
	ios::sync_with_stdio(false);
	int i,j;
	int ans=0;
	cin>>n>>D;
	f(i,1,n){
		cin>>a[i].x>>a[i].h;
	}
	sort(a+1,a+1+n);
	f(i,1,n){
		while(!q.empty()&&a[q.front()].x+D=a[i].h+a[i].h) a[i].l=1;
		while(!q.empty()&&a[q.back()].h<=a[i].h) q.pop_back();
		q.push_back(i);
	}
	while(!q.empty()) q.pop_back();
	ff(i,n,1){
		while(!q.empty()&&a[q.front()].x>a[i].x+D) q.pop_front();
		if(!q.empty()&&a[q.front()].h>=a[i].h+a[i].h) a[i].r=1;
		while(!q.empty()&&a[q.back()].h<=a[i].h) q.pop_back();
		q.push_back(i);
	}
	f(i,1,n){
		if(a[i].l&&a[i].r) ans++;
	}
	cout<

 

你可能感兴趣的:(线段树)