[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; }