zoukankan      html  css  js  c++  java
  • BZOJ2648:SJY摆棋子

    浅谈(K-D) (Tree)https://www.cnblogs.com/AKMer/p/10387266.html

    题目传送门:https://lydsy.com/JudgeOnline/problem.php?id=2648

    (K-D) (Tree)最近点查询裸题,注意先把所有点建好再一个个激活。

    时间复杂度:(O(nlogn))

    空间复杂度:(O(n))

    代码如下:

    #include <cstdio>
    #include <algorithm>
    using namespace std;
     
    const int maxn=5e5+5,inf=2e9;
     
    int n,m,pps,ans,node[maxn];
     
    int read() {
        int x=0,f=1;char ch=getchar();
        for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
        for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
        return x*f;
    }
     
    struct query {
        int opt,x,y;
    }q[maxn];
     
    struct kd_tree {
        int cnt,root;
    	int fa[maxn<<1];
     
        struct point {
            int c[2],mn[2],mx[2],id,ls,rs;
     
            point() {}
     
            point(int _x,int _y,int _id) {
                c[0]=_x,c[1]=_y,id=_id;
                if(id<=n)mn[0]=mx[0]=c[0],mn[1]=mx[1]=c[1];
                else mn[0]=mn[1]=inf,mx[0]=mx[1]=-inf;
    			ls=rs=0;
            }
     
            bool operator<(const point &a)const {
                return c[pps]<a.c[pps];
            }
        }p[maxn<<1];
     
        void update(int u) {
            int ls=p[u].ls,rs=p[u].rs;
            for(int i=0;i<2;i++) {
                int mn=min(p[ls].mn[i],p[rs].mn[i]);
                p[u].mn[i]=min(p[u].mn[i],mn);
                int mx=max(p[ls].mx[i],p[rs].mx[i]);
                p[u].mx[i]=max(p[u].mx[i],mx);
            }
        }
     
        int build(int l,int r,int cmp) {
            int mid=(l+r)>>1,u=mid;pps=cmp;
            nth_element(p+l,p+mid,p+r+1);
    		if(p[u].id>n)node[p[u].id-n]=u;
            if(l<mid)fa[p[u].ls=build(l,mid-1,cmp^1)]=u;
            if(r>mid)fa[p[u].rs=build(mid+1,r,cmp^1)]=u;
            update(u);
            return u;
        }
     
        void prepare() {
            p[0]=point(0,0,2e9);
            for(int i=1;i<=n;i++) {
                int x=read(),y=read();
                p[i]=point(x,y,i);
            }
            for(int i=1;i<=m;i++) {
                int opt=read(),x=read(),y=read();
                q[i].opt=opt,q[i].x=x,q[i].y=y;
                if(opt==1)p[++cnt]=point(x,y,n+i);
            }
            root=build(1,cnt,0);
        }
     
        void arouse(int u) {
    		p[u].mn[0]=p[u].mx[0]=p[u].c[0];
    		p[u].mn[1]=p[u].mx[1]=p[u].c[1];
    		while(fa[u])update(u),u=fa[u];
    		update(u);
        }
     
        int dis(int id,int x,int y) {
            int res=0;
            if(x<p[id].mn[0])res+=p[id].mn[0]-x;
            if(x>p[id].mx[0])res+=x-p[id].mx[0];
            if(y<p[id].mn[1])res+=p[id].mn[1]-y;
            if(y>p[id].mx[1])res+=y-p[id].mx[1];
            return res;
        }
     
        void query(int u,int x,int y,int id) {
            if(p[u].id<id)ans=min(ans,abs(x-p[u].c[0])+abs(y-p[u].c[1]));
            int dl=p[u].ls?dis(p[u].ls,x,y):inf;
            int dr=p[u].rs?dis(p[u].rs,x,y):inf;
            if(dl<dr) {
                if(dl<ans)query(p[u].ls,x,y,id);
                if(dr<ans)query(p[u].rs,x,y,id);
            }
            else {
                if(dr<ans)query(p[u].rs,x,y,id);
                if(dl<ans)query(p[u].ls,x,y,id);
            }
        }
    }T;
     
    int main() {
        T.cnt=n=read(),m=read();
        T.prepare();
        for(int i=1;i<=m;i++) 
            if(q[i].opt==1)T.arouse(node[i]);
            else {
                ans=2e9;
                T.query(T.root,q[i].x,q[i].y,n+i);
                printf("%d
    ",ans);
            }
        return 0;
    }
    
  • 相关阅读:
    Jenkins 主备master-slave模式搭建
    vbox 相关
    jenkins 常见问题汇总
    linux git patch 和patch以及git diff 命令
    Linux中的free命令
    MySQL Show命令的使用
    MySQL 加锁处理分析 转
    共享锁【S锁】 排他锁【X锁】
    MySQL分库分表环境下全局ID生成方案 转
    mysql性能的检查和调优方法
  • 原文地址:https://www.cnblogs.com/AKMer/p/10391879.html
Copyright © 2011-2022 走看看