模板—K-D-tree(P2479 [SDOI2010]捉迷藏)
#include<algorithm>
#include<iostream>
#include<cstdio>
#include<cmath>
#define LL long long
#define MAXN 1000100
using namespace std;
inline LL min(LL a,LL b){return a<b?a:b;}
int n,cmpid;
struct point
{
int x[];
friend bool operator < (point a,point b)
{return a.x[cmpid]<b.x[cmpid];}
}p[MAXN];
struct tree
{
point p;
int mn[],mx[],l,r;
#define l(x) tr[x].l
#define r(x) tr[x].r
#define p(x) tr[x].p
}tr[MAXN];
int Dis(point a,point b)
{
return abs(a.x[]-b.x[])+abs(a.x[]-b.x[]);
}
int min_dis(tree a,point b)
{
int x=max(a.mn[]-b.x[],)+max(b.x[]-a.mx[],);
int y=max(a.mn[]-b.x[],)+max(b.x[]-a.mx[],);
return x+y;
}
int max_dis(tree a,point b)
{
int x=max(abs(a.mx[]-b.x[]),abs(b.x[]-a.mn[]));
int y=max(abs(a.mx[]-b.x[]),abs(b.x[]-a.mn[]));
return x+y;
}
struct KDtree
{
int root,tot,ans;
#define INF 0x7fffffff
void ask_max(point a,int x,int k)
{
if(!x)return;int tem;
if((tem=Dis(p(x),a))>ans)ans=tem;
int l=l(x),r=r(x);
if(a.x[k]<p(x).x[k])swap(l,r);
if(max_dis(tr[l],a)>ans)ask_max(a,l,k^);
if(max_dis(tr[r],a)>ans)ask_max(a,r,k^);
}
int ask_max(point a)
{
ans=-INF;
ask_max(a,root,);
return ans;
}
void ask_min(point a,int x,int k)
{
if(!x)return;int tem;
if((tem=Dis(p(x),a))<ans&&tem!=)ans=tem;
int l=l(x),r=r(x);
if(a.x[k]>p(x).x[k])swap(l,r);//如果a在x有右半区间,先向右搜索。
if(min_dis(tr[l],a)<ans)ask_min(a,l,k^);
if(min_dis(tr[r],a)<ans)ask_min(a,r,k^);
}
int ask_min(point a)
{
ans=INF;
ask_min(a,root,);
return ans;
}
void updata(int x)
{
if(!x)return;
if(l(x))
tr[x].mn[]=min(tr[x].mn[],tr[l(x)].mn[]),
tr[x].mn[]=min(tr[x].mn[],tr[l(x)].mn[]),
tr[x].mx[]=max(tr[x].mx[],tr[l(x)].mx[]),
tr[x].mx[]=max(tr[x].mx[],tr[l(x)].mx[]);
if(r(x))
tr[x].mn[]=min(tr[x].mn[],tr[r(x)].mn[]),
tr[x].mn[]=min(tr[x].mn[],tr[r(x)].mn[]),
tr[x].mx[]=max(tr[x].mx[],tr[r(x)].mx[]),
tr[x].mx[]=max(tr[x].mx[],tr[r(x)].mx[]);
}
void build(int &x,int l,int r,int k)
{
if(l>r)return;
x=++tot;int mid=(l+r)>>;
cmpid=k;
nth_element(p+l,p+mid,p+r+);
p(x)=p[mid];
tr[x].mn[]=tr[x].mx[]=p(x).x[];
tr[x].mn[]=tr[x].mx[]=p(x).x[];
build(l(x),l,mid-,k^);
build(r(x),mid+,r,k^);
updata(x);
}
void build()
{
tot=;
build(root,,n,);
}
}T;
signed main()
{
cin>>n;
for(int i=;i<=n;i++)
cin>>p[i].x[]>>p[i].x[];
T.build();
LL ans=INF;
for(int i=;i<=n;i++)
{
ans=min(ans,T.ask_max(p[i])-T.ask_min(p[i]));
}
cout<<ans<<endl;
}
放一下‘天使玩偶’的标程:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
using namespace std;
int n,m,cmpid;
struct point
{
int x[];
friend bool operator < (point a,point b)
{return a.x[cmpid]<b.x[cmpid];}
}p[];
struct tree
{
point p;
int mx[],mn[],l,r;
#define l(x) tr[x].l
#define r(x) tr[x].r
#define p(x) tr[x].p
}tr[];
int dis(point a,point b){return abs(a.x[]-b.x[])+abs(a.x[]-b.x[]);}
int min_dis(tree a,point b)
{
int x=max(a.mn[]-b.x[],)+max(b.x[]-a.mx[],);
int y=max(a.mn[]-b.x[],)+max(b.x[]-a.mx[],);
return x+y;
}
struct KD_tree
{
int root,tot,ans;
#define INF 0x7fffffff
void ask_min(point a,int x,int k)
{
if(!x)return;int tem;
if((tem=dis(p(x),a))<ans)ans=tem;
int l=l(x),r=r(x);
if(a.x[k]>p(x).x[k])swap(l,r);
if(min_dis(tr[l],a)<ans)ask_min(a,l,k^);
if(min_dis(tr[r],a)<ans)ask_min(a,r,k^);
}
int ask_min(point a)
{
ans=INF;ask_min(a,root,);
return ans;
}
void updata(int x)
{
if(!x)return;
if(l(x))
tr[x].mn[]=min(tr[x].mn[],tr[l(x)].mn[]),
tr[x].mn[]=min(tr[x].mn[],tr[l(x)].mn[]),
tr[x].mx[]=max(tr[x].mx[],tr[l(x)].mx[]),
tr[x].mx[]=max(tr[x].mx[],tr[l(x)].mx[]);
if(r(x))
tr[x].mn[]=min(tr[x].mn[],tr[r(x)].mn[]),
tr[x].mn[]=min(tr[x].mn[],tr[r(x)].mn[]),
tr[x].mx[]=max(tr[x].mx[],tr[r(x)].mx[]),
tr[x].mx[]=max(tr[x].mx[],tr[r(x)].mx[]);
}
void build(int &x,int l,int r,int k)
{
if(l>r)return;
x=++tot;int mid=(l+r)>>;
cmpid=k;
nth_element(p+l,p+mid,p+r+);
p(x)=p[mid];
tr[x].mn[]=tr[x].mx[]=p(x).x[];
tr[x].mn[]=tr[x].mx[]=p(x).x[];
build(l(x),l,mid-,k^);
build(r(x),mid+,r,k^);
updata(x);
}
void build(){tot=;build(root,,n,);}
void insert(point a,int &x,int k)
{
if(!x)
{
x=++tot;p(x)=a;
tr[x].mn[]=tr[x].mx[]=p(x).x[];
tr[x].mn[]=tr[x].mx[]=p(x).x[];
return;
}
if(a.x[k]<p(x).x[k])insert(a,l(x),k^);
else insert(a,r(x),k^);
updata(x);
}
void insert(point a){insert(a,root,);}
}T;
signed main()
{
cin>>n>>m;
for(int i=;i<=n;i++)cin>>p[i].x[]>>p[i].x[];
T.build();int t,x,y;
for(int i=;i<=m;i++)
{
cin>>t>>x>>y;
if(t==)T.insert((point){x,y});
else cout<<T.ask_min((point){x,y})<<endl;;
}
}
模板—K-D-tree(P2479 [SDOI2010]捉迷藏)的更多相关文章
- P2479 [SDOI2010]捉迷藏
传送门 KDtree是个吼东西啊-- 枚举每一个点,然后求出离他距离最远和最近的点的距离,更新答案 然而为什么感觉KDtree只是因为剪枝才能跑得动呢-- //minamoto #include< ...
- [SDOI2010]捉迷藏 K-Dtree
[SDOI2010]捉迷藏 链接 luogu 思路 k-dtree模板题 代码 #include <bits/stdc++.h> #define ls (t[u].ch[0]) #defi ...
- k短路模板(洛谷P2483 [SDOI2010]魔法猪学院)(k短路,最短路,左偏树,priority_queue)
你谷数据够强了,以前的A*应该差不多死掉了. 所以,小伙伴们快来一起把YL顶上去把!戳这里! 俞鼎力的课件 需要掌握的内容: Dijkstra构建最短路径树. 可持久化堆(使用左偏树,因其有二叉树结构 ...
- LCT总结——概念篇+洛谷P3690[模板]Link Cut Tree(动态树)(LCT,Splay)
为了优化体验(其实是强迫症),蒟蒻把总结拆成了两篇,方便不同学习阶段的Dalao们切换. LCT总结--应用篇戳这里 概念.性质简述 首先介绍一下链剖分的概念(感谢laofu的讲课) 链剖分,是指一类 ...
- 洛谷P3690 [模板] Link Cut Tree [LCT]
题目传送门 Link Cut Tree 题目背景 动态树 题目描述 给定n个点以及每个点的权值,要你处理接下来的m个操作.操作有4种.操作从0到3编号.点从1到n编号. 0:后接两个整数(x,y),代 ...
- 洛谷 [P2483] [模板] k短路
人生中的第一道黑题... 其实就是k短路模板 #include <iostream> #include <cstdio> #include <cstring> #i ...
- 【题解】[SDOI2010]捉迷藏
题目链接:https://www.luogu.com.cn/problem/P2479 题目大意:求平面\(n\)个点中,到其它\(n-1\)个点的曼哈顿距离最大和最小距离之差最小的点,求出这个这个距 ...
- [模板] k短路
简介 Dijkstra最短路+A*搜索. 先逆向求所有点到终点的最短路 \(dis[i]\). 定义估价函数 \(f[i] = d[i] + dis[i]\) , 其中 \(d[i]\) 表示当前起点 ...
- [SDOI2010]捉迷藏
嘟嘟嘟 k-d tree板儿题. 建完树后对每一个点求一遍最小和最大曼哈顿距离,是曼哈顿,不是欧几里得. #include<cstdio> #include<iostream> ...
随机推荐
- 严格模式下顶层箭头函数this指向的是全局对象
我们知道普通函数调用,this在非严格模式下指向全局对象,在严格模式下是undefined.那箭头函数呢?我们知道,箭头函数没有自己的this,它的this是最近外层非箭头函数的this,那直接在顶层 ...
- 【solr】schemaFactory配置相关schema.xml
schemaFactory配置相关schema.xml 关于schemaFactory的配置困扰我半天啦,下面来总结一下. 话说,好像是从5.0以后就已经没有schema.xml啦,这是由于Solr ...
- grpc安装
整个过程就是: 1.客户端 发送 数据(以字节流的方式) 2.服务端接收,并解析. 根据 约定 知道要知道执行什么.然后把结果返回客户端 RPC就是 把 1.上述过程封装下,使其操作更加优化 2.使用 ...
- python基本算法题(一)
1.3位水仙花数计算 "3位水仙花数”是指一个三位整数,其各位数字的3次方和等于该数本身. 例如: ABC是一个“3位水仙花数”,则:A的3次方+B的3次方+C的3次方 = ABC. 使用P ...
- 外观模式(Facade)(门面模式、子系统容易使用)
外观(Facade)模式的定义:是一种通过为多个复杂的子系统提供一个一致的接口,而使这些子系统更加容易被访问的模式.该模式对外有一个统一接口,外部应用程序不用关心内部子系统的具体的细节,这样会大大降低 ...
- ML面试1000题系列(51-60)
本文总结ML面试常见的问题集 转载来源:https://blog.csdn.net/v_july_v/article/details/78121924 51.简单说下sigmoid激活函数 常用的非线 ...
- 通过pip工具安装selenium(初次安装、升级、降级)
1.初始安装 语法: install selenium==版本号 2.升级安装 3.降级安装 ----------------------------------------------------- ...
- ASP.NET 自定义服务器控件
文章内容 本文通过创建一个最简单的服务器控件,演示开发服务器端控件的流程. 文章内容整理自MSDN的编程指南,原文地址在文章末尾的资源中. 本文创建一个简单的服务器控件,名为 RedLabel. ...
- 2017年浙工大迎新赛热身赛 L cayun日常之赏月【易错特判】
题目描述(https://www.nowcoder.com/acm/contest/51#question) 在cayun星球月亮大小都有一个规律,月亮为每30天一个周期,在这30天的周期里,月亮的大 ...
- 使用Redis管道提升性能
首发于 樊浩柏科学院 Redis 的 管道 (pipelining)是用来打包多条无关命令批量执行,以减少多个命令分别执行带来的网络交互时间.在一些批量操作数据的场景,使用管道可以显著提升 Redis ...