思路是优化 O(n2logn) 的算法,对整个序列进行分块,然后对块内有无元素分讨处理,目前二分部分出现了问题,求调。
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long ll;
const int inf=1000000001,V=2*inf,blo=200;
int n,fp[1000005],rr,rs,z[1000005],ans[1000005],rp[12005],l[12005],R[1000005],qn,cp[1000005],bel[10000005],d[10000005],rk[12005],bels[12005],q;
short fr[71994005];
int las[71994005];
vector<int> vc[1000005];
vector<pair<int,int> > vcs[1000005];
struct node{
ll x,y;
}c[12005];
int cmp(node aa,node bb){
if(aa.y==bb.y){
return aa.x>bb.x;
}
return aa.y<bb.y;
}
int getblo(int x){
return (x-1)/blo+1;
}
int getxx(int x){
int cur=lower_bound(cp+1,cp+qn+1,x)-cp;
return cur;
}
int cmp2(int aa,int bb){
if(z[aa]==z[bb]){
return aa<bb;
}
return z[aa]<z[bb];
}
int main(){
//freopen("jisuanjihe.in","r",stdin);
// freopen("jisuanjihe.out","w",stdout);
cin>>n>>q;
for(int i=1;i<=n;i++){
cin>>c[i].x>>c[i].y;
c[i].x=c[i].x*c[i].x+c[i].y*c[i].y;
c[i].y*=2;
}
sort(c+1,c+n+1,cmp);
for(int i=1;i<=q;i++){
cin>>z[i]>>R[i];
z[i]+=inf;
cp[i]=z[i];
}
sort(cp+1,cp+q+1);
qn=unique(cp+1,cp+q+1)-cp-1;
for(int i=1;i<=qn;i++){
if((i>=2&&getblo(cp[i])!=getblo(cp[i-1]))||(i==1)){
bel[getblo(cp[i])]=++rs;
}
else{
bel[getblo(cp[i])]=bel[getblo(cp[i-1])];
}
vcs[rs].push_back({cp[i],i});
}
for(int i=1;i<=q;i++){
int t=getblo(z[i]);
if(!d[t]){
d[t]=getxx(z[i]);
}
else{
d[t]=min(d[t],getxx(z[i]));
}
}
for(int i=10000001;i>=1;i--){
if(d[i+1]){
if(!d[i]){
d[i]=d[i+1];
}
else{
d[i]=min(d[i],d[i+1]);
}
}
}
for(int i=1;i<=n;i++){
rk[i]=1;
c[i].x+=inf*c[i].y;
//cout<<c[i].x<<" "<<c[i].y<<endl;
}
for(int i=1;i<=n;i++){
l[i]=rr;
for(int j=1;j<i;j++){
++rr;
fr[rr]=i;
if(c[j].y==c[i].y){
//cout<<i<<" "<<j<<endl;
rk[j]++;
continue;
}
ll D=(c[i].x-c[j].x)/(c[i].y-c[j].y);
D++;
// cout<<D-inf<<" "<<j<<" "<<i<<" "<<(c[i].y-c[j].y)<<endl;
if(D<=cp[1]){
rk[j]++;
}
else{
rk[i]++;
}
if(D<=cp[1]||D>cp[qn]){
continue;
}
// cout<<D<<endl;
ll dt;
if(!bel[getblo(D)]){
dt=d[getblo(D)];
}
else{
int t=getblo(D);
vector<pair<int,int> >::iterator cur=lower_bound(vcs[bel[t]].begin(),vcs[bel[t]].end(),make_pair((int)D,0));
if(cur==vcs[bel[t]].end()){
dt=d[t+1];
}
else{
dt=(*cur).second;
}
}
las[rr]=fp[dt];
fp[dt]=rr;
}
}
// cout<<"狗";
for(int i=1;i<=n;i++){
bels[rk[i]]=i;
}
l[n+1]=rr;
for(int i=1;i<=q;i++){
rp[i]=i;
}
sort(rp+1,rp+q+1,cmp2);
// cout<<"狗";
for(int i=1;i<=q;i++){
if(getxx(z[rp[i]])>=2&&z[rp[i]]!=z[rp[i-1]]){
int now=fp[getxx(z[rp[i]])];
while(now){
int hs=fr[now],ls;
ls=now-l[now];//(hs,ls)
rk[hs]--;
rk[ls]++;
now=las[now];
}
now=fp[getxx(z[rp[i]])];
while(now){
int hs=fr[now],ls;
ls=now-l[now];//(hs,ls)
bels[rk[hs]]=hs;
bels[rk[ls]]=ls;
now=las[now];
}
}
int ls,rs,mid;
ls=1,rs=n;
while(ls<rs){
mid=(ls+rs+1)>>1;
if((c[bels[mid]].x-c[bels[mid]].y*z[rp[i]])<=(R[rp[i]]*R[rp[i]]-(z[rp[i]]-inf)*(z[rp[i]]-inf))){
ls=mid;
}
else{
rs=mid-1;
}
}
if((c[bels[ls]].x-c[bels[ls]].y*z[rp[i]])>(R[rp[i]]*R[rp[i]]-(z[rp[i]]-inf)*(z[rp[i]]-inf))){
ls=0;
}
ans[rp[i]]=ls;
}
for(int i=1;i<=q;i++){
cout<<ans[i]<<endl;
}
return 0;
}