读大佬的博客 附上链接,,图也是人家的 对不起 QAQ

曼哈顿距离

曼哈顿距离:d(i,j)=|X1-X2|+|Y1-Y2|.
也就是横纵坐标差的绝对值的和。

切比雪夫距离

切比雪夫距离:二个点之间的距离定义是其各坐标数值差绝对值的最大值

一个是和、一个是最大值 。废话

曼哈顿距离的图
两者可以相互转换,


切尔雪夫的图

很像?两者可以相互转换
原坐标系中的 曼哈顿距离转切尔雪夫:坐标:(x+y,x-y);
原坐标系中的 切尔雪夫转曼哈顿:坐标:((x+y)/2,(x-y)/2);
两个式子互逆

换了之后 原图中的曼哈顿就等于现在图里的切尔雪夫
有的题中 如果用曼哈顿比较麻烦 就可以换成切尔雪夫
反之也可以

例题:牛客挑战赛34 - D 拉普兰德的愿望

题目大意:
给出n个坐标让求曼哈顿距离>=d的个数就是总的小于d的

然后 用曼哈顿距离怎么做? 不会 好难好难 想了一下午 还很垃圾的想了一个错的,好明显的错误。。。 还给大佬讲了错的。。 尴尬
然后 看了题解
题解:
曼哈顿距离转化为切比雪夫距离 然后只用计算如上图的 以当前点为中心边长为2d的正方形中有多少点 就是 离这个点距离小于d的点的个数 记得不算边界上的 因为题上要求大于等于d的 减去的应该是小于d的

用树状数组存y为i的个数 然后 枚举每个点 每个点只记 正方形的左半部分、枚举的时候顺便把x不符合的删了 y的话在树状数组里 就 前缀和 r的-l的。
哇 机智啊

代码:


```cpp
#include <stdio.h>
#include <algorithm>
using namespace std;
const int maxn = 1e5+5;
struct Node
{
   
    int x,y;
    bool operator < (const Node & a)const {
   
        return x<a.x;
    }
}node[maxn];
int tree[2*maxn];
int l;
int lowbit(int x)
{
   
    return x&-x;
}
void add(int x,int num)
{
   
    while(x<=4*l)
    {
   
        tree[x] += num;
        x+=lowbit(x);
    }
}
int get(int x)
{
   
    int ans = 0;
    while(x>0)
    {
   
        ans += tree[x];
        x-=lowbit(x);
    }
    return ans;
}
typedef long long ll;
int main()
{
   
    int n,d;
    scanf("%d%d%d",&n,&d,&l);
    for(int i = 0; i < n; i ++ )
    {
   
        int x,y;
        scanf("%d%d",&x,&y);
        node[i].x = x+y+2*l;
        node[i].y = x-y+2*l;//怕是负的 就都加个2*l
// printf("%d %d\n",node[i].x,node[i].y);
    }
    sort(node,node+n);
    ll ans = 0;
    for (int lt = 0, r = 0; r < n; r ++ )
    {
   
        while(lt < r && node[lt].x<=node[r].x-d)//把x不在这个区间里的都去了
            add(node[lt++].y,-1);
        int rr = min(4*l, node[r].y + d - 1);//记得不能算边界
        int ll = max(0,node[r].y - d);//同上
        ans += get(rr) - get(ll);
// printf("%d %d %d %d %d %d\n",l,r,get(ll),get(rr),ll,rr);
        add(node[r].y,1);
    }
    printf("%lld\n",1ll*n*(n-1)/2-ans);//答案为 总的减去不符合的
}

这谁顶得住?