题意
在二维平面内有n个气球,选择一个三条等间距的横线和竖线,问能最大打破多少个气球.
思路
枚举x坐标,用线段树维护y坐标(去重).
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
int tree[maxn<<2];
void build(int l,int r,int rt){
tree[rt]=0;
if(l==r) return;
int mid=l+r>>1;
build(rt<<1,l,mid);
build(rt<<1|1,mid+1,r);
}
void update(int p,int val,int l=1,int r=100001,int rt=1){
if(l==r) {
tree[rt]+=val;
return;
}
int mid=l+r>>1;
if(p<=mid) update(p,val,l,mid,rt<<1);
else update(p,val,mid+1,r,rt<<1|1);
tree[rt]=max(tree[rt<<1],tree[rt<<1|1]);
}
vector<int> v[maxn];
int main(){
int n,r;scanf("%d%d",&n,&r);
build(1,1,100001);
for(int i=1;i<=n;i++){
int x,y;
scanf("%d%d",&x,&y);
x++,y++;
v[x].push_back(y);
if(x-r>=1) v[x-r].push_back(y);
if(x-2*r>=1) v[x-2*r].push_back(y);
update(y,1);
if(y-r>=1) update(y-r,1);
if(y-2*r>=1) update(y-2*r,1);
}
int ans=0;
for(int i=1;i<=100001;i++){
for(int j=0;j<v[i].size();j++){
update(v[i][j],-1,1,100001,1);
if(v[i][j]-r>=1) update(v[i][j]-r,-1);
if(v[i][j]-2*r>=1) update(v[i][j]-2*r,-1);
}
ans=max(ans,(int)v[i].size()+tree[1]);
for(int j=0;j<v[i].size();j++){
update(v[i][j],1);
if(v[i][j]-r>=1) update(v[i][j]-r,1);
if(v[i][j]-2*r>=1) update(v[i][j]-2*r,1);
}
}
printf("%d\n",ans);
//system("pause");
return 0;
}