题目

题意: 给n个点和半径r,请问半径为r的图形最多覆盖多少点。这里是指欧几里得距离。

#include<bits/stdc++.h>
using namespace std;
const int N=6e5+5;
struct node{int x,y1,y2,o;}a[N];
inline int cmp(node A,node B){return (A.x==B.x)?(A.o>B.o):(A.x<B.x);}
int refl[N];
struct Segment{
int mx[N<<2],tag[N<<2];
void build(int l,int r,int pos){
mx[pos]=tag[pos]=0;
if(l==r) return;
int mid=(l+r)>>1;
build(l,mid,pos<<1),build(mid+1,r,pos<<1|1);
}
void pushdown(int pos){
tag[pos<<1]+=tag[pos],tag[pos<<1|1]+=tag[pos];
mx[pos<<1]+=tag[pos],mx[pos<<1|1]+=tag[pos];
tag[pos]=0;
}
void pushup(int pos){mx[pos]=max(mx[pos<<1],mx[pos<<1|1]);}
void update(int cl,int cr,int val,int l,int r,int pos){
if(cl<=l&&r<=cr){mx[pos]+=val,tag[pos]+=val;return;}
if(tag[pos]) pushdown(pos);
int mid=(l+r)>>1;
if(cl<=mid) update(cl,cr,val,l,mid,pos<<1);
if(cr>mid) update(cl,cr,val,mid+1,r,pos<<1|1);
pushup(pos);
}
}A;
inline int _rotate(int &x,int &y){
int tmpx=x,tmpy=y;
x=tmpx+tmpy,y=tmpy-tmpx;
}
inline void _get(int &x,int ovo){x=lower_bound(refl+1,refl+ovo+1,x)-refl;}
int main(){
int n,r;scanf("%d%d",&n,&r),r*=2;//r画图可知为2*r;
int tot=0,ovo=0;
for(int i=1,x,y;i<=n;++i){
scanf("%d%d",&x,&y);
_rotate(x,y);//坐标轴逆时针旋转45° 然后横纵坐标再乘以根号2.
a[++tot]=(node){x,y,y+r,1},a[++tot]=(node){x+r,y,y+r,-1};
refl[++ovo]=y,refl[++ovo]=y+r;
}
sort(refl+1,refl+ovo+1);
ovo=unique(refl+1,refl+ovo+1)-(refl+1);
for(int i=1;i<=tot;++i) _get(a[i].y1,ovo),_get(a[i].y2,ovo);
sort(a+1,a+tot+1,cmp);
A.build(1,ovo,1);
int ans=0;
for(int i=1;i<=tot;++i){
A.update(a[i].y1,a[i].y2,a[i].o,1,ovo,1);
ans=max(ans,A.mx[1]);
}
printf("%d\n",ans);
}

该博客讨论了codeforces1184C2问题,涉及如何在给定半径r的情况下,计算覆盖欧几里得空间中最多n个点的图形。内容聚焦于坐标系旋转和固定长宽矩阵在覆盖点数上的优化策略。
495

被折叠的 条评论
为什么被折叠?



