ccz181078

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: :: 管理 ::

随机数据,带修改,求到空间中到给定点距离为给定值的点的编号,唯一解。

建三维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;
}

 

posted on 2017-09-19 12:06  nul  阅读(229)  评论(0编辑  收藏  举报