总之就是各种乱七八糟的KDT卡常即可。。。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#define enc(x) (x=Enc(a,b,las_res,x))
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define db double
#define N 500000
#define dcmp(x,y) (sgn((x)-(y)))
#define debug(x) cerr<<#x<<"="<<x
#define sp <<" "
#define ln <<endl
using namespace std;
inline db indb() { double x;scanf("%lf",&x);return (db)x; }
const db eps=0.00001;
inline db squ(db x) { return x*x; }
inline int sgn(db x) { return x<-eps?-1:x>eps; }
inline db F(db a,db b,db x) { return a*x-b*sin(x); }
inline db Enc(db a,db b,db las,db f,db L=-100,db R=100)
{
//return f;
db mid=(L+R)/2;
while(L+0.000000001<R)
{
db v=F(a,b,las*mid+1);
if(v<f) L=mid;else R=mid;
mid=(L+R)/2;
}
return (L+R)/2;
}
struct P{
static int cur_dim;db x[3];int id;
P(db _x=0,db _y=0,db _z=0,int _id=0) { x[0]=_x,x[1]=_y,x[2]=_z,id=_id; }
inline bool operator<(const P &p)const{return x[cur_dim]<p.x[cur_dim]; }
inline db dis2(const P &p)const
{
db ans=0;
rep(i,0,2) ans+=squ(x[i]-p.x[i]);
return ans;
}
}p[N],q[N],t,mx[N],mn[N],pp[N];
int P::cur_dim=0;int pos[N];
int nc,ch[N][2];
inline int push_up(int x)
{
int lc=ch[x][0],rc=ch[x][1];
rep(i,0,2)
{
if(lc) mx[x].x[i]=max(mx[x].x[i],mx[lc].x[i]),mn[x].x[i]=min(mn[x].x[i],mn[lc].x[i]);
if(rc) mx[x].x[i]=max(mx[x].x[i],mx[rc].x[i]),mn[x].x[i]=min(mn[x].x[i],mn[rc].x[i]);
}
return 0;
}
int build_cnt;
int build(int &rt,P *p,int l,int r,int dim=0)
{
if(l>r) return rt=0;
build_cnt++;
int mid=(l+r)/2;rt=++nc;
P::cur_dim=dim;
nth_element(p+l,p+mid,p+r+1);
pp[rt]=mx[rt]=mn[rt]=p[mid];
pos[p[mid].id]=rt;
build(ch[rt][0],p,l,mid-1,(dim+1)%3);
build(ch[rt][1],p,mid+1,r,(dim+1)%3);
//debug(rt)sp,debug(ch[rt][0])sp,debug(ch[rt][1])sp,debug(mx[rt].id)ln;
return push_up(rt);
}
int ins_cnt;
int ins(int rt,P &q,int dim=0)
{
ins_cnt++;
int g,x;
if(q.x[dim]<pp[rt].x[dim]) g=0;else g=1;
if(ch[rt][g]) ins(ch[rt][g],q,(dim+1)%3);
else x=++nc,ch[rt][g]=x,pos[q.id]=x,pp[x]=mn[x]=mx[x]=q;
return push_up(rt);
}
inline int del(int x)
{
x=pos[x],pp[x].id=mn[x].id=mx[x].id=0;int lc=ch[x][0],rc=ch[x][1];
//rep(i,0,2) mn[x].x[i]=min(mn[lc].x[i],mn[rc].x[i]),mx[x].x[i]=max(mx[lc].x[i],mx[rc].x[i]);
return 0;
}
inline db calc1(int x,P &p)
{
db ans=0;
rep(i,0,2) ans+=squ(max((db)0.0,mn[x].x[i]-p.x[i])+max((db)0.0,p.x[i]-mx[x].x[i]));
return ans;
}
inline db calc2(int x,P &p)
{
db ans=0;
rep(i,0,2) ans+=squ(max(mx[x].x[i]-p.x[i],p.x[i]-mn[x].x[i]));
return ans;
}
int ans;
int qry_cnt;
int query(int x,P &q,db r)
{
qry_cnt++;
if(!x||ans) return 0;
if(mn[x].id&&dcmp(q.dis2(pp[x]),r)==0) return ans=mn[x].id;
db dl=calc1(ch[x][0],q),dr=calc1(ch[x][1],q),d1=calc2(ch[x][0],q),d2=calc2(ch[x][1],q);
//debug(dl)sp,debug(dr)sp,debug(d1)sp,debug(d2)sp,debug(r)ln;
if(d1<d2)
{
if(dl<r+eps&&d1+eps>r) query(ch[x][0],q,r);
if(dr<r+eps&&d2+eps>r) query(ch[x][1],q,r);
}
else{
if(dr<r+eps&&d2+eps>r) query(ch[x][1],q,r);
if(dl<r+eps&&d1+eps>r) query(ch[x][0],q,r);
}
return 0;
}
int main()
{
// freopen("data.in","r",stdin);
// freopen("std.out","w",stdout);
int n,m,rt;scanf("%d%d",&n,&m);
db a=indb(),b=indb(),las_res=0.1;
for(int i=1;i<=n;p[i].id=i,i++)
for(int j=0;j<=2;j++) p[i].x[j]=indb();
for(int i=1;i<=n;i++) q[i]=p[i];build(rt,q,1,n);
while(m--)
{
int opt;scanf("%d",&opt);
if(opt==0)
{
db _i=indb(),x=indb(),y=indb(),z=indb();
enc(x),enc(y),enc(z);
_i=Enc(a,b,las_res,_i,1,n);
int id=(int)(_i+0.5);
// debug(id)sp,debug(x)sp,debug(y)sp,debug(z)ln;
del(id),p[id]=P(x,y,z,id),ins(rt,p[id]);
}
else{
// las_res=2;
db x=indb(),y=indb(),z=indb(),r=indb();
enc(x),enc(y),enc(z),t=P(x,y,z);
r=Enc(a,b,las_res,r,-1000,1000);
// debug(x)sp,debug(y)sp,debug(z)sp,debug(r)ln;
ans=0,query(rt,t,r*r),las_res=ans,printf("%d\n",ans);
}
}
// debug(nc)ln;
// debug(build_cnt)ln;
// debug(ins_cnt)ln;
// debug(qry_cnt)ln;
return 0;
}