题目描述
题解
考场写了35,本机跑5s感觉布星就没调,结果因为把long long存到double里面爆精度WA掉了,实际跑了2s,然后套个平衡规划就过了
把询问离线,两个点到询问点距离的关系只会改变一次,连线做中垂线交y轴即可得到改变的位置,堆维护即可有35,分成10块搞即可AC
code
#include <bits/stdc++.h>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define abs(x) ((x)>0?(x):-(x))
#define sqr(x) ((x)*(x))
#define ll long long
//#define file
using namespace std;
struct type{ll x,y;int id;} a[12002],b[1000001];
struct Type{double s;int x,y;} s;
priority_queue<Type> hp;
int ans[1000001],c[12001],n,Q,i,j,k,l,r,mid,I,l1,r1,S;
char st[21],ch;
ll R;
bool operator < (Type a,Type b) {return a.s>b.s;}
int Read() {int x=0,k=1;ch=getchar(); while (ch<'0' || ch>'9') k=(ch=='-')?-1:k,ch=getchar(); while (ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar(); return k*x;}
void Write(int x) {if (!x) {putchar('0');putchar('
');return;}int i=0; while (x) st[++i]=x%10+'0',x/=10; while (i) putchar(st[i--]);putchar('
');}
bool cmp(type a,type b) {return a.y<b.y || a.y==b.y && a.x<b.x;}
void swap(int &x,int &y) {int z=x;x=y;y=z;}
double js(int i,int j) {if (a[i].y==a[j].y) return 2133333333; return ((double)sqr(a[i].x)+sqr(a[i].y)-sqr(a[j].x)-sqr(a[j].y))/(2*(a[i].y-a[j].y));}
void add(int i,int j) {double s;if (a[i].y!=a[j].y) {s=js(i,j);hp.push({s,a[i].id,a[j].id});};}
int main()
{
#ifdef file
freopen("circle.in","r",stdin);
freopen("circle.out","w",stdout);
#endif
n=Read();Q=Read();
fo(i,1,n) a[i].x=Read(),a[i].y=Read(),a[i].x=abs(a[i].x);
fo(i,1,Q) b[i].y=Read(),b[i].x=Read(),b[i].id=i;
sort(a+1,a+n+1,cmp);
sort(b+1,b+Q+1,cmp);
fo(i,1,n) a[i].id=i,c[i]=i;
S=10;
fo(I,1,S)
{
l1=(I-1)*(n/S)+1;r1=I*(n/S);
if (I==S) r1=n;
fo(i,l1,r1-1) if (a[i].y<a[i+1].y) add(i,i+1);
fo(i,1,Q)
{
while (!hp.empty())
{
s=hp.top();
if (s.s-0.00000001>b[i].y) break;
hp.pop();
if (a[c[s.x]+1].id==s.y)
{
j=c[s.x];
a[0]=a[j],a[j]=a[j+1],a[j+1]=a[0];
++c[s.x],--c[s.y];
if (j>l1 && a[j-1].y<a[j].y) add(j-1,j);
if (j+1<r1 && a[j+1].y<a[j+2].y) add(j+1,j+2);
}
}
R=sqr(b[i].x);
l=l1;r=r1;
while (l<r)
{
mid=(l+r)/2;
if (sqr(a[mid].x)+sqr(a[mid].y-b[i].y)<=R)
l=mid+1; else r=mid;
}
l-=(sqr(a[l].x)+sqr(a[l].y-b[i].y)>R);
ans[b[i].id]+=l-l1+1;
}
if (I<S) while (!hp.empty()) hp.pop();
}
fo(i,1,Q) Write(ans[i]);
}