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

https://www.luogu.org/problemnew/show/P2906#sub

了解奶牛们的人都知道,奶牛喜欢成群结队.观察约翰的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均同属一个群.

给出奶牛们的位置,请计算草原上有多少个牛群,以及最大的牛群里有多少奶牛

参考题解:https://www.cnblogs.com/lidaxin/p/5192127.html

同时因为懒得写splay且set比较清真所以还看了:https://www.cnblogs.com/ChinaHook/p/6985444.html

(是的在之前我不会用set……)

首先看到曼哈顿距离立刻想到我们可以将其分成四种情况讨论(我们碰到过这样的题,比如天使玩偶

那么我们经过漫长的讨论之后我们可以得到上面判别式的变体:max( |(Xi+Yi)-(Xj+Yj)|, |(Xi-Yi)-(Xj-Yj)| )<=c。

我们考虑将点坐标(x,y)变为(x+y,x-y),将max展开得到:

两点为同群满足第一条条件时,当且仅当①|Xi-Xj|<=c且②|Yi-Yj|<=c。

那么我们对X排序(这样单调后O(n)判断①,平衡树中不满足①的点删除即可),用平衡树维护Y的大小关系(lower_bound找到它左右的点与它判断②,其他点显然不用考虑因为如果某点与它为同群则必然与它左/右点同群),满足的点并查集一下即可。

PS:建立一个头和尾防止访问越界,由此可能引发爆int的问题,所以要么判别式移项要么开longlong

#include<set>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=;
const int INF=2e9+;
inline int read(){
int X=,w=;char ch=;
while(ch<''||ch>''){if(ch=='-')w=-;ch=getchar();}
while(ch>=''&&ch<='')X=(X<<)+(X<<)+ch-'',ch=getchar();
return X*w;
}
struct point{
int x,y;
bool operator < (const point& a)const{
return x<a.x||(x==a.x&&y<a.y);
}
}p[N];
multiset<point>s;
multiset<point> ::iterator it;
int fa[N],sz[N],n,c;
inline int find(int x){
return (fa[x]==x)?x:fa[x]=find(fa[x]);
}
inline void unionn(int a,int b){
if(a!=b){fa[a]=b;sz[b]+=sz[a];}
}
int main(){
n=read(),c=read();
for(int i=;i<=n;i++){
int x=read(),y=read();
p[i].x=x+y,p[i].y=x-y,fa[i]=i,sz[i]=;
}
sort(p+,p+n+);
s.insert((point){INF,}),s.insert((point){-INF,});
int front=;
for(int i=;i<=n;i++){
while(p[i].x-c>p[front].x){
s.erase(s.lower_bound((point){p[front].y,front}));
front++;
}
it=s.lower_bound((point){p[i].y,i});
point r=*it,l=*(--it);
if(r.x-c<=p[i].y)unionn(find(r.y),find(i));
if(p[i].y-c<=l.x)unionn(find(l.y),find(i));
s.insert((point){p[i].y,i});
}
int ans=,maxn=;
for(int i=;i<=n;i++){
if(fa[i]==i){
ans++;
maxn=max(maxn,sz[i]);
}
}
printf("%d %d\n",ans,maxn);
return ;
}

+++++++++++++++++++++++++++++++++++++++++++

+本文作者:luyouqi233。               +

+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+

+++++++++++++++++++++++++++++++++++++++++++

最新文章

  1. Linux系统sar命令解析
  2. [Java] Spring + SpringMVC + Maven + JUnit 搭建
  3. VisualSVN Server导入Repository
  4. AFNetwork 作用和用法详解
  5. 【MySQL】PREPARE 的应用
  6. 2016 版 Laravel 系列入门教程(三)【最适合中国人的 Laravel 教程】
  7. 11.Android之常用对话框AlertDialog学习
  8. Windows cmd 颜色,字体,color font set up
  9. CenOS下搭建VPN服务
  10. jsp链接数据库
  11. HDU 3335 Divisibility dancing links 重复覆盖
  12. Activity常用的方法
  13. nginx增加第三方模块
  14. 《http权威指南》读书笔记6
  15. Java EE之Hibernate异常总结【5】java.lang.StackOverflowError[栈溢出]
  16. Unity 场景分页插件 World Streamer 支持无限大地图的解决方案(二)
  17. sqlalchemy 获取计数 count
  18. [LeetCode] 161. One Edit Distance_Medium
  19. C++ chrono 库中的 steady_clock 和 system_clock
  20. hdu 2962 Trucking (最短路径)

热门文章

  1. android学习七 菜单
  2. PyCharm添加Selenium与Appium类库
  3. JAVA Map 之元素定位,冲突碰撞
  4. 373. Partition Array by Odd and Even【LintCode java】
  5. OpenMPI源码剖析1:MPI_Init初探
  6. Java进阶知识点:并发容器背后的设计理念
  7. Ubuntu—安装并运行sublime
  8. 如何在html中把一个图片或者表格覆盖在一张已有图片上的任意位置
  9. IE中的activex控件
  10. Android 数据存储 之 SQLite数据库详解