近9S左右的龟速QAQ竟然过了
本来还写了个线段树处理矩形的情况的,结果好像跪了。
于是弃疗写暴力。
用队列维护一下当前矩形/圆的x范围内的点,然后对每个点暴力判断是否在矩形/圆内。
O(n^2)
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; const int N=250000+5; const double eps=1e-7; int dcmp(double x){ if(fabs(x)<eps)return 0; return x<0?-1:1; } struct point{ double x,y; int id; bool operator < (const point &rhs)const{ return x<rhs.x; } }p[N]; struct rec{ double x1,y1,x2,y2; bool operator < (const rec &rhs)const{ if(dcmp(x1-rhs.x1))return x1<rhs.x1; return x2<rhs.x2; } }r[N]; struct cir{ double x,y,r,a,b; bool operator < (cir rhs)const{ if(dcmp(a-rhs.a))return a<rhs.a; return b<rhs.b; } }c[N]; int n,m,nc,nr; int res[N],q[N]; double sqr(double x){return x*x;} bool inc(cir c,point p){ return dcmp(sqrt(sqr(c.x-p.x)+sqr(c.y-p.y))-c.r)<0; } bool inr(rec r,point p){ return dcmp(r.y1-p.y)<0&&dcmp(p.y-r.y2)<0; } int main(){ //freopen("a.in","r",stdin); //freopen("a.out","w",stdout); scanf("%d%d",&n,&m); char shape[5]; while(n--){ scanf("%s",shape); if(shape[0]=='r'){ nr++; scanf("%lf%lf%lf%lf",&r[nr].x1,&r[nr].y1,&r[nr].x2,&r[nr].y2); }else{ nc++; scanf("%lf%lf%lf",&c[nc].x,&c[nc].y,&c[nc].r); c[nc].a=c[nc].x-c[nc].r; c[nc].b=c[nc].x+c[nc].r; } } if(nr>=1)sort(r+1,r+1+nr); if(nc>=1)sort(c+1,c+1+nc); for(int i=1;i<=m;i++) scanf("%lf%lf",&p[i].x,&p[i].y),p[i].id=i; sort(p+1,p+1+m); int h=0,t=-1,j=1; for(int i=1;i<=nr;i++){ while(j<=m&&dcmp(p[j].x-r[i].x1)<=0)j++; while(h<=t&&dcmp(p[q[h]].x-r[i].x1)<=0)h++; while(j<=m&&dcmp(p[j].x-r[i].x2)<0)q[++t]=j++; for(int k=h;k<=t;k++) if(dcmp(r[i].y1-p[q[k]].y)<0&&dcmp(p[q[k]].y-r[i].y2)<0&&dcmp(p[q[k]].x-r[i].x2)<0)res[p[q[k]].id]++; } h=0;t=-1;j=1; for(int i=1;i<=nc;i++){ while(j<=m&&dcmp(p[j].x-c[i].a)<=0)j++; while(h<=t&&dcmp(p[q[h]].x-c[i].a)<=0)h++; while(j<=m&&dcmp(p[j].x-c[i].b)<0)q[++t]=j++; for(int k=h;k<=t;k++) if(dcmp(sqrt(sqr(p[q[k]].x-c[i].x)+sqr(p[q[k]].y-c[i].y))-c[i].r)<0) res[p[q[k]].id]++; } for(int i=1;i<=m;i++) printf("%d\n",res[i]); return 0; }