treap+并查集

我们能想到一个点和最近点对连接,用并查集维护,但是这个不仅不能求,而且还是不对的,于是就看了题解

把距离转为A(x-y,x+y),这样两点之间的距离就是max(x'-X',y'-Y'),那么就可以求了,我们按转换后的x排序,维护一个区间,最大的x和最小的x差不超过c,然后把y插进treap里,每次查找前驱后继,如果距离小于等于c就连接,最后扫一遍统计答案就行

曼哈顿和切比雪夫距离是可以互相转换的,x=x-y,y=x+y就行,切比雪夫距离转换为曼哈顿距离转换回去也可以

#include<bits/stdc++.h>
using namespace std;
const int N = , seed = , inf = ;
struct data {
int x, y;
data(int x = , int y = ) : x(x), y(y) {}
bool friend operator < (data A, data B) { return A.x < B.x; }
} a[N];
int n, ans, root;
long long c;
pair<int, int> pre, nxt;
int sum[N], fa[N];
struct Treap {
int cnt, P;
pair<int, int> key[N];
int size[N], child[N][], p[N], tot[N];
inline int rand() { P = P * seed + ; return abs(P); }
inline void update(int x) { size[x] = size[child[x][]] + size[child[x][]] + tot[x]; }
inline void rotate(int &x, int t)
{
int y = child[x][t];
child[x][t] = child[y][t ^ ];
child[y][t ^ ] = x;
update(x); update(y); x = y;
}
inline void insert(int &x, pair<int, int> o)
{
if(x == ) { p[x = ++cnt] = rand(); key[x] = o; tot[x] = ; }
else
{
if(key[x] == o) ++tot[x];
else { int t = o > key[x]; insert(child[x][t], o); if(p[child[x][t]] > p[x]) rotate(x, t); }
}
update(x);
}
inline void erase(int &x, pair<int, int> o)
{
if(key[x] == o)
{
if(child[x][] == && child[x][] == ) { --tot[x]; if(tot[x] == ) x = ; else update(x); }
else { int t = p[child[x][]] > p[child[x][]]; rotate(x, t); erase(child[x][t ^ ], o); }
}
else erase(child[x][o > key[x]], o);
update(x);
}
inline void query_pre(int x, pair<int, int> o)
{
if(x == ) return;
if(key[x] > o) query_pre(child[x][], o);
else { if(key[x] > pre) pre = key[x]; query_pre(child[x][], o); }
}
inline void query_nxt(int x, pair<int, int> o)
{
if(x == ) return;
if(key[x] < o) query_nxt(child[x][], o);
else { if(key[x] < nxt) nxt = key[x]; query_nxt(child[x][], o); }
}
} treap;
inline int find(int x) { return x == fa[x] ? x : fa[x] = find(fa[x]); }
inline void connect(int x, int y)
{
int u = find(x), v = find(y);
if(u == v) return;
--ans;
fa[v] = u;
}
int main()
{
// freopen("nabor.in", "r", stdin);
// freopen("nabor.out", "w", stdout);
scanf("%d%lld", &n, &c);
ans = n;
for(int i = ; i <= n; ++i)
{
int x, y;
scanf("%d%d", &x, &y);
a[i] = data(x - y, x + y);
}
a[].x = inf;
sort(a + , a + n + );
treap.insert(root, {-inf, -});
treap.insert(root, {inf, -});
for(int i = ; i <= n; ++i) fa[i] = i;
int l = ;
for(int i = ; i <= n; ++i)
{
pair<int, int> o;
while(l <= i && a[i].x - a[l].x > c)
{
o = make_pair(a[l].y, l);
treap.erase(root, o);
++l;
}
nxt = {inf + , -};
pre = {-inf - , -};
o = make_pair(a[i].y, i);
treap.query_pre(root, o);
treap.query_nxt(root, o);
long long dis_pre, dis_nxt;
treap.insert(root, o);
dis_pre = (long long)a[i].y - (long long)pre.first;
dis_nxt = (long long)nxt.first - (long long)a[i].y;
if(dis_pre <= c && pre.second != -) connect(i, pre.second);
if(dis_nxt <= c && nxt.second != -) connect(i, nxt.second);
}
printf("%d ", ans);
ans = ;
for(int i = ; i <= n; ++i) ++sum[find(i)];
for(int i = ; i <= n; ++i) ans = max(ans, sum[i]);
printf("%d\n", ans);
// fclose(stdin);
// fclose(stdout);
return ;
}

bzoj1604的更多相关文章

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

    [BZOJ1604][Usaco2008 Open]Cow Neighborhoods 奶牛的邻居 试题描述 了解奶牛们的人都知道,奶牛喜欢成群结队.观察约翰的N(1≤N≤100000)只奶牛,你会发 ...

  2. 【BZOJ1604】[Usaco2008 Open]Cow Neighborhoods 奶牛的邻居 Treap+并查集

    [BZOJ1604][Usaco2008 Open]Cow Neighborhoods 奶牛的邻居 Description 了解奶牛们的人都知道,奶牛喜欢成群结队.观察约翰的N(1≤N≤100000) ...

  3. [BZOJ1604] [Usaco2008 Open] Cow Neighborhoods 奶牛的邻居 (queue & set)

    Description 了解奶牛们的人都知道,奶牛喜欢成群结队.观察约翰的N(1≤N≤100000)只奶牛,你会发现她们已经结成了几个“群”.每只奶牛在吃草的时候有一个独一无二的位置坐标Xi,Yi(l ...

  4. bzoj1604 / P2906 [USACO08OPEN]牛的街区Cow Neighborhoods

    P2906 [USACO08OPEN]牛的街区Cow Neighborhoods 考虑维护曼哈顿距离:$\left | x_{1}-x_{2} \right |+\left | y_{1}-y_{2} ...

  5. BZOJ1604 & 洛谷2906:[USACO2008 OPEN]Cow Neighborhoods 奶牛的邻居——题解

    http://www.lydsy.com/JudgeOnline/problem.php?id=1604 https://www.luogu.org/problemnew/show/P2906#sub ...

  6. 【bzoj1604】【[Usaco2008 Open]Cow Neighborhoods】简单的谈谈曼哈顿距离

    (最近p站上不去要死了) Description 了解奶牛们的人都知道,奶牛喜欢成群结队.观察约翰的N(1≤N≤100000)只奶牛,你会发现她们已经结成了几个"群".每只奶牛在吃 ...

  7. 【bzoj1604】[Usaco2008 Open]Cow Neighborhoods 奶牛的邻居 旋转坐标系+并查集+Treap/STL-set

    题目描述 了解奶牛们的人都知道,奶牛喜欢成群结队.观察约翰的N(1≤N≤100000)只奶牛,你会发现她们已经结成了几个“群”.每只奶牛在吃草的时候有一个独一无二的位置坐标Xi,Yi(l≤Xi,Yi≤ ...

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

    传送门 良心题解 #include <set> #include <cstdio> #include <iostream> #include <algorit ...

  9. bzoj1604 牛的邻居 STL

    Description 了解奶牛们的人都知道,奶牛喜欢成群结队.观察约翰的N(1≤N≤100000)只奶牛,你会发现她们已经结成了几个“群”.每只奶牛在吃草的时候有一个独一无二的位置坐标Xi,Yi(l ...

随机推荐

  1. JavaScript:获取上传图片的base64

    文章来源:http://www.cnblogs.com/hello-tl/p/7661535.html 1.HTML代码 <!DOCTYPE html> <html lang=&qu ...

  2. python链家网高并发异步爬虫and异步存入数据

    python链家网二手房异步IO爬虫,使用asyncio.aiohttp和aiomysql 很多小伙伴初学python时都会学习到爬虫,刚入门时会使用requests.urllib这些同步的库进行单线 ...

  3. MySQL-----多对多

    多对多: 示例1: 用户表和相亲记录表 用户表 用户id 用户名                  性别 1 George  男 2 Elizabeth 女 3 Bruce 男 4 Catherine ...

  4. noi.ac NOIP2018 全国热身赛 第二场 T3 color

    [题解] 我们可以发现每次修改之后叶子结点到根的路径最多分为两段:一段白色或者黑色,上面接另一段灰色的.二分+倍增找到分界点,然后更新答案即可. check的时候只需要判断当前节点对应的叶子结点的区间 ...

  5. prometheus监控linux系统

    安装node exporter 创建Systemd服务 #vim /etc/systemd/system/node_exporter.service[Unit]Description=mysql_ex ...

  6. SQL Server 2016 CTP3.2 开荒 Reporting Service 篇

    仅仅是开荒资源页,反正过不了多久就会有新的CTP. 下面是MSDN I Tell you 提供的 不过是中文,个人不是很建议,因为现在大多的资源页都是英文的ed2k://|file|cn_sql_se ...

  7. 《C语言程序设计(第四版)》阅读心得(一)

    本篇开始写我个人觉得谭浩强老师的<C语言程序设计(第四版)>中之前没有认识到,或者忘了的知识.因为本科学过,所以有些简单的东西就没有放进来了,所以可能并不是太全面. 第一章程序设计与语言 ...

  8. 获取webview的截图

    设置webview可以获取截图: webView.setDrawingCacheEnabled(true); 当要进行多次截图时,先要清除之前的缓存: webview.setDrawingCacheE ...

  9. commons-lang常用工具类StringEscapeUtils

    原文:https://my.oschina.net/mousai/blog/88832 在apache commons-lang(2.3以上版本)中为我们提供了一个方便做转义的工具类,主要是为了防止s ...

  10. 【转】使用Python中HTTPParser模块进行简单的html解析

    http://www.cnblogs.com/coser/archive/2012/01/09/2317076.html