【清华集训2014】 uoj #40 卡常数 - KD-Tree

总之就是各种乱七八糟的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;
}

猜你喜欢

转载自blog.csdn.net/Mys_C_K/article/details/82926643
今日推荐