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. leetcode-169求众数

    求众数 思路: 记录每个元素出现的次数,然后查找到众数 代码: class Solution: def majorityElement(self, nums: List[int]) -> int ...

  2. [BZOJ3932] [CQOI2015]任务查询系统(主席树 || 树状数组 套 主席树 + 差分 + 离散化)

    传送门 看到这个题有个很暴力的想法, 可以每一个时间点都建一颗主席树,主席树上叶子节点 i 表示优先级为 i 的任务有多少个. 当 x 到 y 有个优先级为 k 的任务时,循环 x 到 y 的每个点, ...

  3. MT6755 平台手机皮套驱动实现

    是自己写注册一个input device,模仿keypad,在对应的中断处理函数中上报power key的键值. 具体实现代码如下: 在 alps/kernel-3.10/drivers/misc/m ...

  4. node.js 写流 createWriteStream----由浅入深

    createWriteStream 写流 基于fs模块 let fs=require("fs"); createWriteStream创建一个写流 我们先创建一个2.txt要写入的 ...

  5. msp430入门编程04

    msp430中C语言的变量与数据类型 msp430入门学习 msp430入门编程

  6. QT-Embedded-4.5.3在海思35xx上移植

    QT4.5.3在海思3520A上移植步骤-修订版 2015年3月29日星期日, 16:59:03 1.首先要保证已经安装了海思的交叉编译器: #arm-hi  + Tab key to show wh ...

  7. echarts模拟highcharts实现折线图的虚实转换

    多的不说直接上代码: <html><html lang="en"><head> <meta charset="utf-8&quo ...

  8. Ubuntu 16.04安装GTX960闭源驱动

    GTX960的闭源要Nvidia 346版才行,闭源驱动能很大提升显卡的性能,例如双显示输出等,缺点是不开源. 有以下方式来安装: 1.命令行: sudo add-apt-repository -y ...

  9. USB2.0的最高传输速率

    USB2.0除了拥有USB1.1中规定的1.5Mbps和12Mbps两个传输模式以外,还增加了480Mbps高速数据传输模式(注:第二版USB2.0的传输速率将达800Mbps,最高理想值1600Mb ...

  10. JAVA调用动态链接库(dll)

        菜鸡爬坑 基础知识  因为某个东西的keygen我只会在win下生成!! 所以只能出此下策!!之前一直是android下用jni调用so文件,现在试下java在win平台下调用dll 首先还是 ...