[BZOJ1604][Usaco2008 Open]Cow Neighborhoods 奶牛的邻居
[BZOJ1604][Usaco2008 Open]Cow Neighborhoods 奶牛的邻居
试题描述
输入
第1行输入N和C,之后N行每行输入一只奶牛的坐标.
输出
仅一行,先输出牛群数,再输出最大牛群里的牛数,用空格隔开.
输入示例
输出示例
数据规模及约定
见“试题描述”
题解
把曼哈顿距离转换成“切比雪夫”距离,即每个点 (x, y) 变成 (x+y, x-y),那么两点 (x1, y1) (x2, y2) 间曼哈顿距离 = max{ |x1 - x2|, |y1 - y2| },于是把新点按 x 排序,滑动窗口控制成 c 的宽度,然后平衡树维护 y 这一维,每次找到一个点的前驱、后继如果 y 坐标相差小于等于 c 就在并查集中合并一下。最后随便统计统计。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
using namespace std; int read() {
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() {
int n = read(), c = read();
for(int i = 1; i <= n; i++) {
int x = read(), y = read();
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;
}
[BZOJ1604][Usaco2008 Open]Cow Neighborhoods 奶牛的邻居的更多相关文章
- [BZOJ1604] [Usaco2008 Open] Cow Neighborhoods 奶牛的邻居 (queue & set)
Description 了解奶牛们的人都知道,奶牛喜欢成群结队.观察约翰的N(1≤N≤100000)只奶牛,你会发现她们已经结成了几个“群”.每只奶牛在吃草的时候有一个独一无二的位置坐标Xi,Yi(l ...
- [BZOJ1604][Usaco2008 Open]Cow Neighborhoods 奶牛的邻居 (Treap+单调队列)
题面 了解奶牛们的人都知道,奶牛喜欢成群结队.观察约翰的N(1≤N≤100000)只奶牛,你会发现她们已经结成了几个"群".每只奶牛在吃草的时候有一个独一无二的位置坐标Xi,Yi( ...
- [BZOJ1604] [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居(好题)
传送门 良心题解 #include <set> #include <cstdio> #include <iostream> #include <algorit ...
- 【BZOJ1604】[Usaco2008 Open]Cow Neighborhoods 奶牛的邻居 Treap+并查集
[BZOJ1604][Usaco2008 Open]Cow Neighborhoods 奶牛的邻居 Description 了解奶牛们的人都知道,奶牛喜欢成群结队.观察约翰的N(1≤N≤100000) ...
- BZOJ 1604: [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居
题目 1604: [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居 Time Limit: 5 Sec Memory Limit: 64 MB Description ...
- bzoj 1604 [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居(set+并查集)
Description 了解奶牛们的人都知道,奶牛喜欢成群结队.观察约翰的N(1≤N≤100000)只奶牛,你会发现她们已经结成了几个“群”.每只奶牛在吃草的 时候有一个独一无二的位置坐标Xi,Yi( ...
- 【BZOJ】1604: [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居(set+并查集+特殊的技巧)
http://www.lydsy.com/JudgeOnline/problem.php?id=1604 这题太神了... 简直就是 神思想+神做法+神stl.. 被stl整的我想cry...首先,, ...
- bzoj 1604: [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居——排序+贪心+set
Description 了解奶牛们的人都知道,奶牛喜欢成群结队.观察约翰的N(1≤N≤100000)只奶牛,你会发现她们已经结成了几个“群”.每只奶牛在吃草的时候有一个独一无二的位置坐标Xi,Yi(l ...
- BZOJ1604 & 洛谷2906:[USACO2008 OPEN]Cow Neighborhoods 奶牛的邻居——题解
http://www.lydsy.com/JudgeOnline/problem.php?id=1604 https://www.luogu.org/problemnew/show/P2906#sub ...
随机推荐
- java 移位运算符
java中有三种移位运算符 << : 左移运算符,num << 1,相当于num乘以2 >> : 右移运算符,num >& ...
- web安全性测试用例
建立整体的威胁模型,测试溢出漏洞.信息泄漏.错误处理.SQL 注入.身份验证和授权错误. 1. 输入验证 客户端验证 服务器端验证(禁用脚本调试,禁用Cookies) 1.输入很大的数(如4,29 ...
- jenkins 入门教程(中)
接上回继续,本文以我托管在bitbucket上的一个开源项目spring-boot-rest-framework做为演示,讲解如何创建自动化部署. 一.创建item 点击ok继续,item的详情页面很 ...
- css 隔行变色,表单布局
隔行变色: #list1 li:nth-of-type(odd){ background:#00ccff;}奇数行 #list1 li:nth-of-type(even){ background:# ...
- ExtJS4随笔(1) -- 在VS中加入Ext4的智能提示
将辅助文件加入到Web工程内即可. 辅助文件
- 谁让APP工程师产生了泡沫?
这两年移动互联网比较火,移动APP的开发人员也是比较紧缺. 面试了一个做APP的,能力很一般,态度也比较傲慢.最后感觉肯定不会用这个人了,但是出于验证自己想法的目的,还是很诚恳地以一个决定录取他的态度 ...
- Python笔记(3)迭代器与生成器
参考自:http://www.cnblogs.com/huxi/category/251137.html 迭代器 迭代器是访问集合内元素的一种方式,他不能倒退只能一直迭代下去.可以写到for循环in后 ...
- UISearchBar控件-让我们来搞定!(转)
转载自:http://blog.sina.com.cn/s/blog_7b9d64af0101dfg8.html 最近用到搜索功能.于是,经过不断的研究,终于,有点懂了. 那就来总结一下吧,好 ...
- 解决:Microsoft Office Word已停止工作
1/按组合键WIN+R打开运行对话框 2/在打开框中键入%USERPROFILE%\AppData\Roaming\Microsoft\Templates,单击“确定”按钮 3/在打开的窗口鼠标右键删 ...
- java高新技术-可变参数与OverLoad相关面试题分析
可变参数 可变参数的特点: 只能出现在参数列表的最后: ...位于变量类型和变量名之间,前后有无空格都可以: 调用可变参数的方法时,编译器为该可变参数隐含创建一个数组,在方法中以数组的形式访问可变参数 ...