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\n",ans);
        }
    return 0;
}
BZOJ2648:SJY摆棋子的更多相关文章
- BZOJ2648: SJY摆棋子&&2716: [Violet 3]天使玩偶
		BZOJ2648: SJY摆棋子 BZOJ2716: [Violet 3]天使玩偶 BZOJ氪金无极限... 其实这两道是同一题. 附上2648的题面: Description 这天,SJY显得无聊. ... 
- [BZOJ2648] SJY摆棋子  kd-tree
		2648: SJY摆棋子 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 5421 Solved: 1910[Submit][Status][Disc ... 
- Bzoj2648 SJY摆棋子
		Time Limit: 20 Sec Memory Limit: 128 MB Submit: 3128 Solved: 1067 Description 这天,SJY显得无聊.在家自己玩.在一个 ... 
- BZOJ2648 SJY摆棋子(KD-Tree)
		板子题. #include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> # ... 
- 【kd-tree】bzoj2648 SJY摆棋子
		#include<cstdio> #include<cmath> #include<algorithm> using namespace std; #define ... 
- 2019.01.14 bzoj2648: SJY摆棋子(kd-tree)
		传送门 kd−treekd-treekd−tree模板题. 题意简述:支持在平面上插入一个点,求对于一个点的最近点对. 思路:cdqcdqcdq是一种很不错的分治方法 只是好像码量有点窒息 所以我用了 ... 
- KDTree(Bzoj2648: SJY摆棋子)
		题面 传送门 KDTree 大概就是一个分割\(k\)维空间的数据结构,二叉树 建立:每层选取一维为关键字,把中间的点拿出来,递归左右,有个\(STL\)函数nth_element可以用一下 维护:维 ... 
- [bzoj2648]SJY摆棋子(带插入kd-tree)
		解题关键:带插入kdtree模板题. #include<iostream> #include<cstdio> #include<cstring> #include& ... 
- luogu4169 [Violet]天使玩偶/SJY摆棋子 / bzoj2648 SJY摆棋子 k-d tree
		k-d tree + 重构的思想,就能卡过luogu和bzoj啦orz #include <algorithm> #include <iostream> #include &l ... 
- 【BZOJ2648】SJY摆棋子(KD-Tree)
		[BZOJ2648]SJY摆棋子(KD-Tree) 题面 BZOJ Description 这天,SJY显得无聊.在家自己玩.在一个棋盘上,有N个黑色棋子.他每次要么放到棋盘上一个黑色棋子,要么放上一 ... 
随机推荐
- jq中ajax的dataType:"json"是指什么?
			dataType String 预期服务器返回的数据类型.如果不指定,jQuery 将自动根据 HTTP 包 MIME 信息来智能判断,比如XML MIME类型就被识别为XML.在1.4中,JSON就 ... 
- java写出图形界面
			1. 做出简单的窗体 package javaGUI; import java.awt.BorderLayout; import java.awt.Color; import javax.swing. ... 
- poj 1703 Find them, Catch them 【并查集 新写法的思路】
			题目地址:http://poj.org/problem?id=1703 Sample Input 1 5 5 A 1 2 D 1 2 A 1 2 D 2 4 A 1 4 Sample Output N ... 
- 1.1nginx安装
			1.必要软件准备 安装 pcre为了支持 rewrite 功能,我们需要安装 pcre# yum install pcre* //如过你已经装了,请跳过这一步 安装 openssl需要 ssl 的 ... 
- firefox和chrome实现页面打印自动分页
			在Firefox和chrome中直接调用打印功能的js方法是 window.print(); 但是如果页面很长,那么就需要分页,这时只需要在页面中添加css属性即可,如果想自动分页,则如下所示 < ... 
- linux基础(6)-shell编程
			shell脚本 shell脚本程序:以文件形式存放批量的linux命令集合,该文件能够被shell释放执行.通常由一段linux命令.shell命令.控制语句以及注释语句构成. shell脚本特点: ... 
- 利用RandomAccessFile类在指定文件指定位置插入内容
			package File; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; ... 
- HDU3047 Zjnu Stadium
			本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ... 
- volume image
			http://docs.openstack.org/user-guide/cli_nova_launch_instance_from_volume.html http://docs.openstack ... 
- JDBC方式操作数据库
			1.读取配置文件,我将配置信息写入配置文件(.properties)中,方便后期数据库变更后或者其他项目使用,扩展性好些,尽量避免硬编码. driver=oracle.jdbc.driver.Orac ... 
