• [bzoj2648/2716]SJY摆棋子


    平面上有n个点,要求支持插入一个点和查询一个点的最近点距离 n,m<=500000

    用kdtree实现,但是复杂度貌似没法保证.....(莫名加了替罪羊重建更慢了...)

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #define INF 2000000000
    #define MN 1000000
    using namespace std;
    inline int read()
    {
        int x = 0 , f = 1; char ch = getchar();
        while(ch < '0' || ch > '9'){ if(ch == '-') f = -1;  ch = getchar();}
        while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}
        return x * f;
    }
    int n,now,m;
    inline int abs(int x){return x<0?-x:x;}
    struct P{
        int d[2],mx[2],mn[2],l,r;
        int& operator[](int x){return d[x];}
        bool operator<(const P&x)const{return d[now]<x.d[now];}
        friend int dis(P x,P y){return abs(x.d[0]-y.d[0])+abs(x.d[1]-y.d[1]);}
    }t[MN+5];
    
    struct KD_TREE{
        P p[MN+5],T;int ans;
        void update(int x)
        {
            int l=p[x].l,r=p[x].r;
            for(int i=0;i<2;i++)
            {
                if(l) p[x].mn[i]=min(p[x].mn[i],p[l].mn[i]),
                      p[x].mx[i]=max(p[x].mx[i],p[l].mx[i]);
                if(r) p[x].mn[i]=min(p[x].mn[i],p[r].mn[i]),
                      p[x].mx[i]=max(p[x].mx[i],p[r].mx[i]);
            }
        }
        void ins(int x,int th)
        {
            if(T[th]>=p[x][th])
            {
                if(p[x].r) ins(p[x].r,th^1);
                else 
                {
                    int r=p[x].r=++n;p[r]=T;
                    for(int i=0;i<2;i++)
                        p[r].mn[i]=p[r].mx[i]=T[i];
                }
            }
            else
            {
                if(p[x].l) ins(p[x].l,th^1);
                else
                {
                    int l=p[x].l=++n;p[l]=T;
                    for(int i=0;i<2;i++)
                        p[l].mn[i]=p[l].mx[i]=T[i];
                }
            }
            update(x);
        }
        int getmn(P x)
        {
            int sum=0;
            for(int i=0;i<2;i++)
            {
                sum+=max(x.mn[i]-T[i],0);
                sum+=max(T[i]-x.mx[i],0); 
            }
            return sum;
        }
        int build(int l,int r,int th)
        {
            int mid=l+r>>1;now=th;
            nth_element(t+l,t+mid,t+r+1);
            p[mid]=t[mid];
            for(int i=0;i<2;i++)
                p[mid].mx[i]=p[mid].mn[i]=p[mid][i];
            if(l<mid) p[mid].l=build(l,mid-1,th^1);
            if(mid<r) p[mid].r=build(mid+1,r,th^1);
            update(mid);
            return mid;
        }
        void querymn(int k)
        {
            ans=min(ans,dis(p[k],T));
            int dl=INF,dr=INF;
            if(p[k].l) dl=getmn(p[p[k].l]);
            if(p[k].r) dr=getmn(p[p[k].r]);    
            if(dl>dr)
            {    
                if(dr<ans) querymn(p[k].r);
                if(dl<ans) querymn(p[k].l);
            }
            else 
            {
                if(dl<ans) querymn(p[k].l);
                if(dr<ans) querymn(p[k].r);
            }
        }
    }kd;
    int rt,ans=INF;
    
    int main()
    {
        n=read();m=read();
        for(int i=1;i<=n;i++)
            t[i][0]=read(),t[i][1]=read();
        rt=kd.build(1,n,0);
        for(int i=1;i<=m;i++)
        {
            int op=read();kd.T[0]=read();kd.T[1]=read();
            if(op==1) kd.ins(rt,0);
            else 
            {
                kd.ans=INF;kd.querymn(rt);
                printf("%d
    ",kd.ans);
            }
        }
        return 0;
    }
  • 相关阅读:
    自学软件测试获取学习资源途径有哪些?
    微信发红包-测试分析
    软件测试初级经验
    面试
    电商项目
    LoadRunner11的安装流程+破解+汉化+下载
    Oracle和Mysql操作上的一些区别
    Android模拟器,ADB命令
    logging
    heapq
  • 原文地址:https://www.cnblogs.com/FallDream/p/bzoj2648.html
Copyright © 2020-2023  润新知