团
题目
【题目描述】
现在有一个无向图 $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\times 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 }