[BZOJ1604] [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居(好题)

传送门

 

良心题解

 

#include <set>
#include <cstdio>
#include <iostream>
#include <algorithm>
#define N 100001
#define LL long long
#define INF (~(1 << 31))

using namespace std;

int n, c, h = 1, ans, ans1;
int f[N], sum[N];

struct node
{
	LL x, y;
	node(int x = 0, int y = 0) : x(x), y(y) {}
}p[N];

multiset <node> s;
multiset <node> :: iterator it;

inline bool operator < (const node &a, const node &b)
{
	return a.x < b.x;
}

inline int read()
{
	int x = 0, f = 1;
	char ch = getchar();
	for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1;
	for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - '0';
	return x * f;
}

inline int find(int x)
{
	return x == f[x] ? x : f[x] = find(f[x]);
}

inline int merge(int x, int y)
{
	x = find(x);
	y = find(y);
	if(x ^ y)
	{
		f[x] = y;
		ans--;
	}
}

int main()
{
	int i;
	LL x, y;
	ans = n = read();
	c = read();
	for(i = 1; i <= n; i++) f[i] = i;
	for(i = 1; i <= n; i++)
	{
		x = read();
		y = read();
		p[i].x = x + y;
		p[i].y = x - y;
	}
	sort(p + 1, p + n + 1);
	s.insert(node(-INF, 0));
	s.insert(node(INF, 0));
	for(i = 1; i <= n; i++)
	{
		while(p[i].x - p[h].x > c)
		{
			s.erase(s.lower_bound(node(p[h].y, h)));
			++h; 
		}
		y = p[i].y;
		it = s.lower_bound(node(p[i].y, i));
		node r = *it, l = *--it;
		if(r.x - y <= c) merge(r.y, i);
		if(y - l.x <= c) merge(l.y, i);
		s.insert(node(p[i].y, i));
	}
	for(i = 1; i <= n; i++) sum[find(i)]++;
	for(i = 1; i <= n; i++) ans1 = max(ans1, sum[i]);
	printf("%d %d\n", ans, ans1);
	return 0;
}

  

posted @ 2017-09-20 19:14  zht467  阅读(180)  评论(0编辑  收藏  举报