标签:欧几里得 struct get href second spm lan sqrt printf
欧几里得距离:
\(n\) 维空间的表示就是
感觉好装的样子……
曼哈顿距离
还是感觉好装的样子
切比雪夫距离
就是坐标差的绝对值的极值
然后我们思考曼哈顿距离和切比雪夫距离的关系:
请在纸上建一个二维坐标系,然后画一个与原点曼哈顿距离为 \(5\) 的正方形 \(S_1\)
然后再画一个切比雪夫距离为 \(5\) 的正方形 \(S_2\)
看看它们,是不是有某种奇妙的联系:\(S_1\) 旋转 \(45\) 度后放大为原来原来的两倍就是 \(S_2\)
互相转化的公式为$(x,y) \ on\ S_1 \rightarrow(\frac{x+y}{2},\frac{x-y}{2}) \ on\ S_2 $
这里可以用来使某些题的处理更加方便,比如:
题意转化:
给一个二维平面和一堆点,如果两个点的曼哈顿距离小于等于定值就连边
最后求图上连通块个数
\(n\le 10^5\)
曼哈顿两个维度有点头疼,不好处理,那我们转切比雪夫
这样我们把距离转成了以每个点为原点,在定边长切比雪夫距离矩形中框点
我们上 \(map\) 扫描线就行了
我们在处理每个点的时候就直接找那个离他 \(y\) 最近的上下两个就行了
因为那个点已经考虑了前面的点
#include<bits/stdc++.h>
using namespace std;
#define int long long
namespace yspm{
inline int read()
{
int res=0,f=1; char k;
while(!isdigit(k=getchar())) if(k==‘-‘) f=-1;
while(isdigit(k)) res=res*10+k-‘0‘,k=getchar();
return res*f;
}
const int N=1e5+10;
struct node{
int x,y;
#define x(i) p[i].x
#define y(i) p[i].y
}p[N];
int ans,n,fa[N],r;
inline int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
inline bool cmp(node a,node b)
{
return a.x<b.x;
}
map<int,int> mp;
signed main()
{
n=read(); r=read();
for(int i=1,tx,ty;i<=n;++i)
{
fa[i]=i; tx=read(),ty=read();
x(i)=(tx+ty); y(i)=(tx-ty);
}
mp[1e15+10]=-1;
mp[-1e15-10]=-1;
sort(p+1,p+n+1,cmp);
int now=1;
for(int i=1;i<=n;++i)
{
while(now<n&&x(now)+r<x(i))
{
if(mp[y(now)]==now) mp.erase(y(now));
++now;
}
map<int,int>::iterator it=mp.lower_bound(y(i));
if(y(i)+r>=(*it).first)
{
int t=(*it).second;
if(find(t)!=find(i))
{
fa[find(t)]=find(i),ans--;
}
}
it--;
if(y(i)<=(*it).first+r)
{
int t=(*it).second;
if(find(t)!=find(i))
{
fa[find(t)]=find(i),ans--;
}
}
mp[y(i)]=i;
}printf("%lld\n",ans+n);
return 0;
}
}
signed main(){return yspm::main();}
标签:欧几里得 struct get href second spm lan sqrt printf
原文地址:https://www.cnblogs.com/yspm/p/12784289.html