bzoj2648: SJY摆棋子

本机ac的重构kdtree没有不重构快???bzoj鬼机

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while('0'<=ch&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}

int u[2];
struct KDtree
{
    int lc,rc,p[2],mn[2],mx[2];
}tr[1100000];int trlen,rt;
void add()
{
    int now=++trlen;
    tr[now].p[0]=tr[now].mn[0]=tr[now].mx[0]=u[0];
    tr[now].p[1]=tr[now].mn[1]=tr[now].mx[1]=u[1];
}
void insert()
{
    add();
    if(rt==0){rt=trlen;return ;}
    int now=rt,w=0;
    while(1)
    {
        tr[now].mn[0]=min(tr[now].mn[0],tr[trlen].mn[0]);
        tr[now].mx[0]=max(tr[now].mx[0],tr[trlen].mx[0]);
        tr[now].mn[1]=min(tr[now].mn[1],tr[trlen].mn[1]);
        tr[now].mx[1]=max(tr[now].mx[1],tr[trlen].mx[1]);
        
        if(tr[trlen].p[w]<tr[now].p[w])
        {
            if(tr[now].lc==0){tr[now].lc=trlen;return ;}
            else now=tr[now].lc;
        }
        else
        {
            if(tr[now].rc==0){tr[now].rc=trlen;return ;}
            else now=tr[now].rc;
        }
        w^=1;
    }
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~insert~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int cw;bool cmp(KDtree t1,KDtree t2){return t1.p[cw]==t2.p[cw]?t1.p[cw^1]<t2.p[cw^1]:t1.p[cw]<t2.p[cw];}
void clear(int now)
{
    tr[now].lc=tr[now].rc=0;
    tr[now].mn[0]=tr[now].mx[0]=tr[now].p[0];
    tr[now].mn[1]=tr[now].mx[1]=tr[now].p[1];
}
void update(int now)
{
    int lc=tr[now].lc,rc=tr[now].rc;
    for(int i=0;i<=1;i++)
    {
        if(lc!=0)
        {
            tr[now].mn[i]=min(tr[now].mn[i],tr[lc].mn[i]);
            tr[now].mx[i]=max(tr[now].mx[i],tr[lc].mx[i]);
        }
        if(rc!=0)
        {
            tr[now].mn[i]=min(tr[now].mn[i],tr[rc].mn[i]);
            tr[now].mx[i]=max(tr[now].mx[i],tr[rc].mx[i]);
        }
    }
}
int rebuild(int l,int r,int w)
{
    int mid=(l+r)/2;
    cw=w;nth_element(tr+l,tr+mid,tr+r+1,cmp);
    clear(mid);
    if(l<mid)tr[mid].lc=rebuild(l,mid-1,w^1);
    if(mid<r)tr[mid].rc=rebuild(mid+1,r,w^1);
    update(mid);
    return mid;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~rebuild~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int ans;
int getdis(int now)
{
    if(now==0)return 2147483647;
    int ret=0;
    for(int i=0;i<=1;i++)
    {
        if(u[i]<tr[now].mn[i])ret+=tr[now].mn[i]-u[i];
        if(tr[now].mx[i]<u[i])ret+=u[i]-tr[now].mx[i];
    }
    return ret;
}
void findans(int now,int w)
{
    ans=min(ans,abs(u[0]-tr[now].p[0])+abs(u[1]-tr[now].p[1]));
    int lc=tr[now].lc,rc=tr[now].rc;
    int dl=getdis(lc),dr=getdis(rc);
    if(dl<dr)
    {
        if(dl<ans)findans(lc,w^1);
        if(dr<ans)findans(rc,w^1);
    }
    else
    {
        if(dr<ans)findans(rc,w^1);
        if(dl<ans)findans(lc,w^1);
    }
}
//~~~~~~~~~~~~~~~~~~~~~~~~findans~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int main()
{
    freopen("a.in","r",stdin);
    freopen("a.out","w",stdout);
    int n,Q,op;
    n=read(),Q=read(); trlen=0,rt=0;
    for(int i=1;i<=n;i++)
        u[0]=read(),u[1]=read(),add();
    rt=rebuild(1,trlen,0);
    while(Q--)
    {
        op=read(),u[0]=read(),u[1]=read();
        if(op==1)
        {
            insert();
            //if(trlen%100000==0)rt=rebuild(1,trlen,0);
        }
        else
        {
            ans=2147483647;
            findans(rt,0);
            printf("%d\n",ans);
        }
    }
    return 0;
}
posted @ 2018-12-07 12:51  AKCqhzdy  阅读(135)  评论(0编辑  收藏  举报