[BZOJ1604][Usaco2008 Open]Cow Neighborhoods 奶牛的邻居

[BZOJ1604][Usaco2008 Open]Cow Neighborhoods 奶牛的邻居

1．两只奶牛的曼哈顿距离不超过C(1≤C≤10^9)，即lXi - xil+IYi - Yil≤C.
2．两只奶牛有共同的邻居．即，存在一只奶牛k，使i与k，j与k均同属一个群．
给出奶牛们的位置，请计算草原上有多少个牛群，以及最大的牛群里有多少奶牛

1行输入NC，之后N行每行输入一只奶牛的坐标．

4 2
1 1
3 3
2 2
10 10

2 3

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
using namespace std;

int x = 0, f = 1; char c = getchar();
while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
return x * f;
}

#define maxn 100010
#define oo 2147483647
struct Node {
int v, r, id;
Node() {}
Node(int _1, int _2, int _3): v(_1), r(_2), id(_3) {}
bool operator < (const Node& t) const { return v != t.v ? v < t.v : id < t.id; }
bool operator == (const Node& t) const { return v == t.v && id == t.id; }
} ns[maxn];
int rt, ToT, ch[2][maxn], fa[maxn];
void rotate(int u) {
int y = fa[u], z = fa[y], l = 0, r = 1;
if(z) ch[ch[1][z]==y][z] = u;
if(ch[1][y] == u) swap(l, r);
fa[u] = z; fa[y] = u; fa[ch[r][u]] = y;
ch[l][y] = ch[r][u]; ch[r][u] = y;
return ;
}
void insert(int& o, int v, int id) {
if(!o) {
ns[o = ++ToT] = Node(v, rand(), id);
return ;
}
bool d = ns[o] < Node(v, -1, id);
insert(ch[d][o], v, id); fa[ch[d][o]] = o;
if(ns[ch[d][o]].r > ns[o].r) {
int t = ch[d][o];
rotate(t); o = t;
}
return ;
}
void del(int& o, int v, int id) {
if(!o) return ;
if(ns[o] == Node(v, -1, id)) {
if(!ch[0][o] && !ch[1][o]) o = 0;
else if(!ch[0][o]) {
int t = ch[1][o]; fa[t] = fa[o]; o = t;
}
else if(!ch[1][o]) {
int t = ch[0][o]; fa[t] = fa[o]; o = t;
}
else {
bool d = ns[ch[1][o]].r > ns[ch[0][o]].r;
int t = ch[d][o]; rotate(t); o = t;
del(ch[d^1][o], v, id);
}
}
else {
bool d = ns[o] < Node(v, -1, id);
del(ch[d][o], v, id);
}
return ;
}
Node Findlow(int o, int v, int id) {
Node err(-oo, 233, -1), que(v, -1, id);
if(!o) return err;
bool d = ns[o] < que;
return max(ns[o] < que ? ns[o] : err, Findlow(ch[d][o], v, id));
}
Node Findupp(int o, int v, int id) {
Node err(oo, 233, -1), que(v, -1, id);
if(!o) return err;
bool d = ns[o] < que;
return min(que < ns[o] ? ns[o] : err, Findupp(ch[d][o], v, id));
}

struct Point {
int x, y;
Point() {}
Point(int _, int __): x(_), y(__) {}
bool operator < (const Point& t) const { return x != t.x ? x < t.x : y < t.y; }
} ps[maxn];

int pa[maxn], siz[maxn];
int findset(int x) { return x == pa[x] ? x : pa[x] = findset(pa[x]); }

int main() {
for(int i = 1; i <= n; i++) {
ps[i] = Point(x + y, x - y);
}

sort(ps + 1, ps + n + 1);
int cnt = n, mxs = 1;
for(int i = 1; i <= n; i++) pa[i] = i, siz[i] = 1;
int l = 1, r = 1;
for(; r <= n; r++) {
while(l <= r && ps[r].x - ps[l].x > c) del(rt, ps[l].y, l), l++;
Node tmp = Findlow(rt, ps[r].y, r);
//      printf("tmp: %d %d\n", tmp.id, tmp.v);
if(tmp.v != -oo && ps[r].y - tmp.v <= c) {
int u = findset(r), v = findset(tmp.id);
if(u != v) siz[u] += siz[v], mxs = max(mxs, siz[u]), pa[v] = u, cnt--;
}
tmp = Findupp(rt, ps[r].y, r);
//      printf("tmp: %d %d\n", tmp.id, tmp.v);
if(tmp.v != oo && tmp.v - ps[r].y <= c) {
int u = findset(r), v = findset(tmp.id);
if(u != v) siz[u] += siz[v], mxs = max(mxs, siz[u]), pa[v] = u, cnt--;
}
insert(rt, ps[r].y, r);
}

printf("%d %d\n", cnt, mxs);

return 0;
}


posted @ 2016-12-16 15:59  xjr01  阅读(142)  评论(0编辑  收藏  举报