平面點對問題,切比雪夫距離

題目描述

給定平面的n個點(n<=1e5),所有座標的絕對值在50000以內,現在問你有多少對點之間的距離不小於d。這裏距離描述爲兩點的曼哈頓距離,即dist=|xi-xj|+|yi-yj|。

思路

如果將平面上小於等於d的曼哈頓距離畫出來,會是一個菱形

 

切比雪夫距離:平面上兩個點(x1,y1)(x2,y2)的切比雪夫距離爲max⁡(∣x1−x2∣,∣y1−y2∣),其中∣x∣爲x的絕對值

將曼哈頓距離轉換爲切比雪夫距離後,我們發現切比雪夫距離固定的點呈正方形

這樣我們就可以先將數據離線,按照yy的大小對點進行排序,然後用樹狀數組維護長度爲dd的正方形區域內點的個數即可,這部分代碼相對就比較模板了

#include <bits/stdc++.h>
#define int long long
using namespace std;

const int maxn=1e6+10;
int n,d,fk;
const int fix=5e5+10;
struct Point{
    int x,y;
    bool operator < (const Point &rhs)const{
        return x<rhs.x;
    }
}node[maxn];
int lowbit(int x){
    return x&-x;
}
int c[maxn];
void add(int x,int v){
    while(x<maxn){
        c[x]+=v;
        x+=lowbit(x);
    }
}
int Sum(int x){
    int res=0;
    while(x>0){
        res+=c[x];
        x-=lowbit(x);
    }
    return res;
}
signed main(){
    scanf("%lld%lld%lld",&n,&d,&fk);
    d--;
    for(int i=1;i<=n;i++){
        int x,y;
        scanf("%lld%lld",&x,&y);
        //轉化爲切比雪夫座標
        node[i].x=x+y;
        node[i].y=x-y+fix;
    }
    sort(node+1,node+n+1);
    int ans=0;
    for(int i=1,j=1;i<=n;i++){
        while(j<i&&node[i].x-node[j].x>d){
            add(node[j].y,-1);
            j++;
        }
        ans+=Sum(node[i].y+d)-Sum(node[i].y-d-1);
        add(node[i].y,1);
    }
    ans=n*(n-1)/2-ans;
    printf("%lld\n",ans);
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章