题目:https://www.cometoj.com/contest/59/problem/D?problem_id=2713
题意:给你一个正方形,然后给你n个点,这个正方形能随意放哪,要求那个正方形能覆盖的最多点是多少个
思路:我们其实可以把题目转换一下,我们可以以每个点为中心,我们就可以以那个点+正方形边长,就代表正方形在这个范围内就能覆盖到当前点
然后我们就相当与求一个点被覆盖的最多次数是多少,我们利用扫描线,我们每次入边加进去,然后我们求区间最大值来持续更新即可,因为如果一点
值为3就代表被三个正方形所覆盖,那么选择这个位置就能盖三个点
#include<bits/stdc++.h> #define maxn 400005 #define mod 1000000007 #define ld (d<<1) #define rd (d<<1|1) using namespace std; typedef long long ll; struct sss { ll l,r,h; ll val; sss(){}; sss(ll a,ll b,ll c,ll d){ l=a; r=b; h=c; val=d; }; }ss[maxn*4]; ll X[maxn*4]; ll n,k; ll num; int cmp(struct sss x,struct sss y){ if(x.h==y.h) return x.val>y.val; return x.h<y.h; } ll sum[maxn*4],cnt[4*maxn]; ll xx[maxn]; void push_up(int id) { sum[id]=max(sum[id*2],sum[id*2+1])+cnt[id]; return ; } void modify(int ql,int qr,int flag,int l,int r,int id) { //cout<<ql<<" "<<qr<<" "<<l<<" "<<r<<endl; if(ql<=l&&r<=qr) { sum[id]+=flag; cnt[id]+=flag; //push_up(id); return ; } int mid=(l+r)/2; if(ql<=mid) { modify(ql,qr,flag,l,mid,2*id); } if(qr>mid) { modify(ql,qr,flag,mid+1,r,2*id+1); } push_up(id); return ; } int main(){ scanf("%lld%lld",&n,&k); ll x,y; for(int i=0;i<n;i++){ scanf("%lld%lld",&x,&y); X[num]=x; ss[num++]=sss(x,x+k,y,(ll)1); X[num]=x+k; ss[num++]=sss(x,x+k,y+k,(ll)(-1)); } sort(ss,ss+num,cmp); sort(X,X+num); int m=unique(X,X+num)-X; ll mx=0; for(int i=0;i<num;i++){ int l=lower_bound(X,X+m,ss[i].l)-X; int r=lower_bound(X,X+m,ss[i].r)-X; if(l<=r) modify(l,r,ss[i].val,0,m-1,1); mx = max(mx,sum[1]); } printf("%lld",mx); }