• 题目

    【题目描述】

    现在有一个无向图 $G = (V, E)$,其中 $V = { 1,2,cdots,n} $。对于 $V$ 中的任意一个点 $v$,有两个相关的点权 $f_x(v),f_y(v)$。

    $(i,j) in E $ 当且仅当 $ |f_x(i)-f_x(j)| +|f_y(i)-f_y(j)| le d $。

    求 $G$ 的最大团的点数。

    【输入格式】

    输入第一行读入两个整数 $n,d$,分别表示 $|V|$ 和连边的距离限制。

    接下来 $n$ 行,第 $i$ 行两个整数 $f_x(v),f_y(v)$,表示点权。

    【输出格式】

    输出一个数表示最大团的大小。

    【样例输入】

    4 1
    1 1
    2 1
    1 1
    2 2

    【样例输出】

    3

    【数据范围与提示】

    | 测试点 | $n$ | $x,y,d$ |
    | ------ | -------------------- | ---------------------- |
    | 1,2 | $1 le n le 10$ | $1 le x,y,d le 10$ |
    | 3,4 | $1 le n le 500$ | $1 le x,y,d le 10^3$ |
    | 5,6 | $1 le n le 3,000$ | $1 le x,y,d le 10^8$ |
    | 7,8 | $1 le n le 10^5$ | $1 le x,y,d le 10^8$ |
    | 9,10 | $1 le n le 3 imes 10^5$ | $1 le x,y,d le 10^8$ |

    题解

    首先由 $ |f_x(i)-f_x(j)| +|f_y(i)-f_y(j)| le d $ 可以发现求的是平面上两点的曼哈顿距离,然后就变成边长为 $ d $ 菱形的平面覆盖

    但是菱形不是很好操作,然后尝试将坐标系旋转 $ 45°$,于是坐标就变成了 $ (x-y,x+y) $,即切比雪夫距离

    根据定义,切比雪夫距离为 $max(|x1−x2|,|y1−y2|)$,就很好覆盖了

    对于矩形覆盖,可以考虑用线段树动态解决,动态维护保证一维(例如 $x$ 轴) $leq d$,然后直接查询另一维即可

    代码

     1 #include<bits/stdc++.h>
     2 #define LL long long
     3 #define _(d) while(d(isdigit(ch=getchar())))
     4 using namespace std;
     5 int R(){
     6     int x;bool f=1;char ch;_(!)if(ch=='-')f=0;x=ch^48;
     7     _()x=(x<<3)+(x<<1)+(ch^48);return f?x:-x;}
     8 const int N=3e5+6;
     9 int n,m,d,Y[N],ans,tr[N<<2],tg[N<<2];
    10 struct node{int x,y;}s[N];
    11 bool cmp(node a,node b){return a.x<b.x||(a.x==b.x&&a.y<b.y);}
    12 #define LB(x) lower_bound(Y+1,Y+1+m,s[x].y-d)-Y
    13 #define UB(x) upper_bound(Y+1,Y+1+m,s[x].y)-Y-1
    14 #define Ls rt<<1
    15 #define Rs rt<<1|1
    16 void update(int rt,int l,int r,int ql,int qr,int v){
    17     if(ql<=l&&qr>=r){
    18         tg[rt]+=v,tr[rt]+=v;
    19         return;    
    20     }
    21     int mid=l+r>>1;
    22     if(ql<=mid)update(Ls,l,mid,ql,qr,v);
    23     if(qr>mid)update(Rs,mid+1,r,ql,qr,v);
    24     tr[rt]=max(tr[Ls],tr[Rs])+tg[rt];
    25     return;
    26 }
    27 int main(){
    28     n=R(),d=R();
    29     for(int i=1,x,y;i<=n;i++)
    30         x=R(),y=R(),s[i]=(node){x-y,x+y},Y[i]=x+y;
    31     sort(s+1,s+1+n,cmp),sort(Y+1,Y+1+n);
    32     m=unique(Y+1,Y+1+n)-Y-1;
    33     for(int l=1,r=1;r<=n;l++){
    34         while(r<=n&&s[r].x-s[l].x<=d)
    35             update(1,1,n,LB(r),UB(r),1),r++;
    36         ans=max(ans,tr[1]);
    37         update(1,1,n,LB(l),UB(l),-1);
    38     }
    39     cout<<ans<<endl;
    40     return 0;
    41 }
    View Code
  • 相关阅读:
    UVA 408 (13.07.28)
    linux概念之用户,组及权限
    Java实现 蓝桥杯 历届试题 网络寻路
    Java实现 蓝桥杯 历届试题 约数倍数选卡片
    Java实现 蓝桥杯 历届试题 约数倍数选卡片
    Java实现 蓝桥杯 历届试题 约数倍数选卡片
    Java实现 蓝桥杯 历届试题 约数倍数选卡片
    Java实现 蓝桥杯 历届试题 约数倍数选卡片
    Java实现 蓝桥杯 历届试题 九宫重排
    Java实现 蓝桥杯 历届试题 九宫重排
  • 原文地址:https://www.cnblogs.com/chmwt/p/11167194.html
Copyright © 2020-2023  润新知