题意:现在给你n个点 现在让你横着划三条线间距为r 然后竖着划三条线间距同样为r 现在让你求经过最多的点数
思路:我们首先建一棵关于y区间的线段树 然后枚举x轴 每次更新重叠的点 然后再更新回去 找一个最大值
#include <bits/stdc++.h> using namespace std; const double pi = acos(-1.0); const int N = 1e5+7; const int inf = 0x3f3f3f3f; const double eps = 1e-6; typedef long long ll; const ll mod = 1e7+9; int n,d; struct tree{ int l,r; ll v; }t[N<<4]; int yy[N<<2]; vector<int> xx[N<<2]; void pushup(int p){ t[p].v=max(t[p<<1].v,t[p<<1|1].v); } void build(int p,int l,int r){ t[p].l=l; t[p].r=r; if(l==r){ t[p].v=yy[l]+yy[l+d]+yy[l+2*d]; return ; } int mid=(l+r)>>1; build(p<<1,l,mid); build(p<<1|1,mid+1,r); pushup(p); } void update(int p,int x,int val){ if(t[p].l==t[p].r&&t[p].l==x){ t[p].v+=val; return ; } int mid=(t[p].l+t[p].r)>>1; if(x<=mid) update(p<<1,x,val); else update(p<<1|1,x,val); pushup(p); } void work(int x,int val){ update(1,x,val); if(x-d>=0) update(1,x-d,val); if(x-2*d>=0) update(1,x-2*d,val); } int main(){ ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin>>n>>d; int pox=0; int poy=0; for(int i=1;i<=n;i++){ int x,y; cin>>x>>y; pox=max(pox,x); poy=max(poy,y); yy[y]++; xx[x].push_back(y); } build(1,0,poy); ll ans=0; for(int i=0;i<=pox;i++){ ll tmp=xx[i].size()+xx[i+d].size()+xx[i+2*d].size(); for(int j=0;j<xx[i].size();j++){ work(xx[i][j],-1); } for(int j=0;j<xx[i+d].size();j++){ work(xx[i+d][j],-1); } for(int j=0;j<xx[i+2*d].size();j++){ work(xx[i+2*d][j],-1); } ans=max(ans,t[1].v+tmp); for(int j=0;j<xx[i].size();j++){ work(xx[i][j],1); } for(int j=0;j<xx[i+d].size();j++){ work(xx[i+d][j],1); } for(int j=0;j<xx[i+2*d].size();j++){ work(xx[i+2*d][j],1); } } cout<<ans<<endl; }