http://www.lydsy.com/JudgeOnline/problem.php?id=1604

这题太神了。。。

简直就是 神思想+神做法+神stl。。

被stl整的我想cry。。。首先,,erase的时候如果没有这个元素。。。。。。那么。。。。。(TAT)否则你就要先find(重载<)然后要注意multiset,因为你重载的<运算只判<的话会将值相同(假如这是个结构,有多种元素,它只会判断你重载符号的运算满不满足,,而不去匹配其它项。。所以会错。。)的去掉。。。。。// upd:因为multiset一次删完了所有相同的东西囧QAQ

并且为了避免re。。我们要插入2个边界元素(同时要注意算术溢出!!我wa了几次。。)

说这题的做法:

首先我们来分析|X-x|+|Y-y|,怎么看都感觉不对。。。。。。。。。。。。我们来变一下。。

因为是绝对值,所以有四种情况,但是你拆完后会发现,会变成这样

X-x+Y-y -> (X+Y)-(x+y)

X-x+y-Y -> (X-Y)-(x-y)

x-X+Y-y -> -( (X-Y)-(x-y) )

x-X+y-Y -> -( (X+Y)-(x+y) )

这四种情况,我们可以发现,答案就是

max( |(X+Y)-(x+y)|, |(X-Y)-(x-y)| )

那么我们可以对每个点处理成(X+Y, X-Y)的形式

那么处理后怎么做呢?

我们对这些新的点按新的x排序

然后维护一个队列,里边对应的两两元素的x轴之差都<=c,即每次加入一个元素进来时,如果队列中最小的x值(即队头)与这个值的差>c,那么队头出队列。

这样保证了这些队列中的元素在x轴范围内是符合条件的,即我们做了max两边元素的左边一个。

那么怎么做右边的一个呢

我们将当且所有可能的节点维护一种数据结构存y,其中保证y的差都在范围内(这里不同于上边的x,这里只是保证至少有一个y与另一个y之差小于c,即这些都在一个集合里边)

那么怎么维护新加入进来的元素呢。

很简单,因为之前的y都是满足这个条件的,所以我们只需要找一个比当前要加入的点的y小的(最大的那个)和一个比y大的(最小的那个),然后判断是否差在c里边

如果满足,直接加入这个集合。

正确性显然。

而我们怎么维护答案集合呢,因为我们加入队列的方式是直接比较队头,则队列里的集合不一定是完整的集合(因为有可能满足的点已经出队了),那么我们就用并查集维护他们。。

#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <iostream>
#include <algorithm>
#include <queue>
#include <set>
using namespace std;
#define rep(i, n) for(int i=0; i<(n); ++i)
#define for1(i,a,n) for(int i=(a);i<=(n);++i)
#define for2(i,a,n) for(int i=(a);i<(n);++i)
#define for3(i,a,n) for(int i=(a);i>=(n);--i)
#define for4(i,a,n) for(int i=(a);i>(n);--i)
#define CC(i,a) memset(i,a,sizeof(i))
#define read(a) a=getint()
#define print(a) printf("%d", a)
#define dbg(x) cout << #x << " = " << x << endl
#define printarr(a, n, m) rep(aaa, n) { rep(bbb, m) cout << a[aaa][bbb]; cout << endl; }
inline const int getint() { int r=0, k=1; char c=getchar(); for(; c<'0'||c>'9'; c=getchar()) if(c=='-') k=-1; for(; c>='0'&&c<='9'; c=getchar()) r=r*10+c-'0'; return k*r; }
inline const int max(const int &a, const int &b) { return a>b?a:b; }
inline const int min(const int &a, const int &b) { return a<b?a:b; } const int N=100005, oo=~0u>>1;
int p[N], sum[N], front, c, n, ans, mx;
struct dat { int x, y; }a[N];
multiset<dat> s;
set<dat>::iterator it;
inline const bool operator< (const dat &a, const dat &b) { return a.x<b.x; }
const int ifind(const int &x) { return x==p[x]?x:p[x]=ifind(p[x]); }
inline void un(const int &x, const int &y) { int fx=ifind(x), fy=ifind(y); if(fx!=fy) p[fx]=fy, --ans; } int main() {
read(n); read(c);
int x, y; ans=n;
for1(i, 1, n) read(x), read(y), a[i].x=x+y, a[i].y=x-y, p[i]=i;
sort(a+1, a+1+n); front=1;
s.insert((dat){oo, 0}); s.insert((dat){-oo, 0});
for1(i, 1, n) {
while(a[i].x-a[front].x>c) {
s.erase(s.lower_bound((dat){a[front].y, front}));
++front;
}
long long y=a[i].y;
it=s.lower_bound((dat){a[i].y, i});
dat r=*it, l=*--it;
if((long long)r.x-y <= c) un(r.y, i);
if(y-(long long)l.x <= c) un(l.y, i);
s.insert((dat){a[i].y, i});
}
for1(i, 1, n) ++sum[ifind(i)];
for1(i, 1, n) mx=max(mx, sum[i]);
printf("%d %d", ans, mx);
return 0;
}

Description

了解奶牛们的人都知道,奶牛喜欢成群结队.观察约翰的N(1≤N≤100000)只奶牛,你会发现她们已经结成了几个“群”.每只奶牛在吃草的时候有一个独一无二的位置坐标Xi,Yi(l≤Xi,Yi≤[1..10^9];Xi,Yi∈整数.当满足下列两个条件之一,两只奶牛i和j是属于同一个群的:
  1.两只奶牛的曼哈顿距离不超过C(1≤C≤10^9),即lXi - xil+IYi - Yil≤C.
  2.两只奶牛有共同的邻居.即,存在一只奶牛k,使i与k,j与k均同属一个群.
    给出奶牛们的位置,请计算草原上有多少个牛群,以及最大的牛群里有多少奶牛

Input

第1行输入N和C,之后N行每行输入一只奶牛的坐标.

Output

仅一行,先输出牛群数,再输出最大牛群里的牛数,用空格隔开.

Sample Input

4 2
1 1
3 3
2 2
10 10

* Line 1: A single line with a two space-separated integers: the
number of cow neighborhoods and the size of the largest cow
neighborhood.

Sample Output

2 3

OUTPUT DETAILS:
There are 2 neighborhoods, one formed by the first three cows and
the other being the last cow. The largest neighborhood therefore
has size 3.

HINT

Source

【BZOJ】1604: [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居(set+并查集+特殊的技巧)的更多相关文章

  1. BZOJ 1604: [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居

    题目 1604: [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居 Time Limit: 5 Sec  Memory Limit: 64 MB Description ...

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

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

  3. bzoj 1604 [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居(set+并查集)

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

  4. bzoj 1604: [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居——排序+贪心+set

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

  5. BZOJ 1604 [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居:队列 + multiset + 并查集【曼哈顿距离变形】

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1604 题意: 平面直角坐标系中,有n个点(n <= 100000,坐标范围10^9) ...

  6. bzoj 1604: [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居 曼哈顿生成树

    大致题意:统计平面上由曼哈顿距离小于等于c的点对组成联通块的个数. 曼哈顿生成树的模板题.有关讲解:http://blog.csdn.net/acm_cxlove/article/details/88 ...

  7. bzoj 1604: [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居【切比雪夫距离+并查集+multiset】

    参考:http://hzwer.com/4361.html 坐标开long long,inf开大点 先曼哈顿转切比雪夫(x+y,x-y),距离就变成了max(x',y'): 先按x排序,维护两个指针, ...

  8. BZOJ 1604 [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居 Treap

    题意:链接 方法: Treap 解析: 前几道资格赛的题水的不行,这道Gold的题就够分量辣. 首先这个曼哈顿距离啥的肯定能做文章,怎么转化是个问题,自己玩了一会没玩出来,就查了查曼哈顿距离的转化,发 ...

  9. 【BZOJ】1604: [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居

    [算法]并查集+平衡树+数学+扫描线 [题解] 经典曼哈顿距离转切比雪夫距离. 曼哈顿距离:S=|x1-x2|+|y1-y2|<=c 即:max(x1-x2+y1-y2,x1-x2-y1+y2, ...

随机推荐

  1. Laravel 教程 - Web 开发实战入门 ( Laravel 5.5 )购买链接

      Laravel 教程 - Web 开发实战入门 ( Laravel 5.5 )购买链接: 推荐给你高品质的实战课程 https://laravel-china.org/courses?rf=158 ...

  2. Jquery重新学习之七[Ajax运用总结A]

    Jquery中Ajax的运用是另外一个重点,平时项目经常会用它进行一些异步操作:其核心是通过XMLHttpRequest对象以一种异步的方式,向服务器发送数据请求,并通过该对象接收请求返回的数据,从而 ...

  3. 神经网络中 BP 算法的原理与 Python 实现源码解析

    最近这段时间系统性的学习了 BP 算法后写下了这篇学习笔记,因为能力有限,若有明显错误,还请指正. 什么是梯度下降和链式求导法则 假设我们有一个函数 J(w),如下图所示. 梯度下降示意图 现在,我们 ...

  4. ItelliJ基于Gradle创建及发布Web项目(一)

    背景:安装IntelliJ,去官网下载. 创建WEB项目 1. File->New Project,在弹出的选项框中勾选Web,如下图. IntelliJ默认使用Gradle,感谢Gradle. ...

  5. java语言国际化--ResouceBundle、struts

    一.Java国际化 我们使用java.lang.Locale来构造Java国际化的情境. java.lang.Locale代表特定的地理.政治和文化.需要Locale来执行其任务的操作叫语言环境敏感的 ...

  6. layui 数据表格 根据值(1=业务,2=机构)显示中文名称

    数据是用ThinkPHP5操作 类型是固定4个, 用layui templet - 自定义模板 方法一: {field:'type', title: '类型', width: 200, templet ...

  7. [Jobdu] 题目1522:包含min函数的栈

    题目描述: 定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的min函数. 输入: 输入可能包含多个测试样例,输入以EOF结束.对于每个测试案例,输入的第一行为一个整数n(1<=n< ...

  8. Entity Framework底层操作封装V2版本号(2)

    这个类是真正的数据库操作类.上面的那个类仅仅是调用了这个封装类的方法进行的操作 using System; using System.Collections.Generic; using System ...

  9. Xilinx-7Series-FPGA高速收发器使用学习—RX接收端介绍

    上一篇博文介绍了GTX的发送端,这一篇将介绍GTX的RX接收端,GTX RX接收端的结构和TX发送端类似,数据流方向相反,不过和发送端也有一些区别,GTX的RX接收端结构图如图1所示: 图1 下面将根 ...

  10. android自定义控件(1)-自定义控件属性

    那么还是针对我们之前写的自定义控件:开关按钮为例来说,在之前的基础上,我们来看看有哪些属性是可以自定义的:按钮的背景图片,按钮的滑块图片,和按钮的状态(是开还是关),实际上都应该是可以在xml文件中直 ...