随机数据,带修改,求到空间中到给定点距离为给定值的点的编号,唯一解。
建三维kdtree,对查询用可行性剪枝在树上找,由于数据随机,插入删除时不需要维护平衡。
#include<bits/stdc++.h> using namespace std; typedef double ld; const ld _0=1e-6; int n,m,res; ld _a,_b,la=0.1,X[3],R; void mins(ld&a,ld b){if(a>b)a=b;} void maxs(ld&a,ld b){if(a<b)a=b;} ld f(ld x){return x=la*x+1,_a*x-_b*sin(x);} void $(ld&x){ ld L=-101,R=100000; while(R-L>1e-9){ ld M=(L+R)*.5; f(M)<x?L=M:R=M; } x=(L+R)*.5; } char ib[10000007],*ip=ib; int _(){ int x=0; while(*ip<48)++ip; while(*ip>47)x=x*10+*ip++-48; return x; } ld _Lf(){ ld x=0; bool f=0; while(*ip<48)*ip++=='-'?f=1:0; while(*ip>47)x=x*10+(*ip++-48); if(*ip=='.'){ ld a=.1; for(++ip;*ip>47;x+=(*ip++-48)*a,a*=.1); } return f?-x:x; } ld max(ld a,ld b){return a>b?a:b;} ld near(ld x,ld l,ld r){return x<l?l-x:max(x-r,0);} ld far(ld x,ld l,ld r){return max(r-x,x-l);} ld dis(ld a,ld b,ld c){return a*a+b*b+c*c;} struct node{ node*c[2],*f; ld x[3],mn[3],mx[3]; int id; bool chk1(){ return this && dis(near(X[0],mn[0],mx[0]),near(X[1],mn[1],mx[1]),near(X[2],mn[2],mx[2]))<R+_0 && dis( far(X[0],mn[0],mx[0]), far(X[1],mn[1],mx[1]), far(X[2],mn[2],mx[2]))>R-_0; } bool chk2(){ return id&&fabs(dis(x[0]-X[0],x[1]-X[1],x[2]-X[2])-R)<_0; } void init(int ID,bool d){ id=ID; for(int i=0;i<3;++i){ x[i]=_Lf(); if(d)$(x[i]); mn[i]=mx[i]=x[i]; } } void up(){ if(id)for(int i=0;i<3;++i)mn[i]=mx[i]=x[i]; else for(int i=0;i<3;++i)mn[i]=1e10,mx[i]=-1e10; for(int i=0;i<2;++i)if(c[i]){ c[i]->f=this; if(c[i]->mn[0]>c[i]->mx[0])c[i]=0; else for(int j=0;j<3;++j){ mins(mn[j],c[i]->mn[j]); maxs(mx[j],c[i]->mx[j]); } } } }ns[133333],*np=ns,*rt,*nr[67777]; int D=0; bool operator<(const node&a,const node&b){ return a.x[D]<b.x[D]; } node*build(node*l,node*r){ if(l==r)return 0; node*m=l+(r-l>>1); nth_element(l,m,r); D=(D+1)%3; m->c[0]=build(l,m); m->c[1]=build(m+1,r); m->up(); D=(D+2)%3; return m; } void ins(node*w,node*a,int D){ int d=a->x[D]>w->x[D]; if(w->c[d])ins(w->c[d],a,(D+1)%3); else w->c[d]=a; w->up(); } bool find(node*w){ if(!w->chk1())return 0; if(w->chk2())return res=w->id,1; return find(w->c[0])||find(w->c[1]); } int main(){ fread(ib,1,sizeof(ib),stdin); n=_(),m=_(),_a=_Lf(),_b=_Lf(); for(int i=1;i<=n;++i)np++->init(i,0); rt=build(ns,np); for(node*a=ns;a!=np;++a)nr[a->id]=a; while(m--){ int op=_(); if(op){ X[0]=_Lf(); X[1]=_Lf(); X[2]=_Lf(); R=_Lf(); $(X[0]),$(X[1]),$(X[2]),$(R); R*=R; find(rt); la=res; printf("%d\n",res); }else{ ld _id=_Lf(); $(_id); int id=round(_id); node*u=nr[id]; for(u->id=0;u;u->up(),u=u->f); np->init(id,1); ins(rt,nr[id]=np++,0); } } return 0; }