嘟嘟嘟




k-d tree板儿题。

建完树后对每一个点求一遍最小和最大曼哈顿距离,是曼哈顿,不是欧几里得。

#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<vector>
#include<stack>
#include<queue>
using namespace std;
#define enter puts("")
#define space putchar(' ')
#define Mem(a, x) memset(a, x, sizeof(a))
#define In inline
typedef long long ll;
typedef double db;
const ll INF = 1e18;
const db eps = 1e-8;
const int maxn = 1e5 + 5;
inline ll read()
{
ll ans = 0;
char ch = getchar(), last = ' ';
while(!isdigit(ch)) {last = ch; ch = getchar();}
while(isdigit(ch)) {ans = (ans << 1) + (ans << 3) + ch - '0'; ch = getchar();}
if(last == '-') ans = -ans;
return ans;
}
inline void write(ll x)
{
if(x < 0) x = -x, putchar('-');
if(x >= 10) write(x / 10);
putchar(x % 10 + '0');
} int n, Dim;
struct Tree
{
int ch[2], id;
ll d[2], Min[2], Max[2];
In bool operator < (const Tree& oth)const
{
return d[Dim] < oth.d[Dim];
}
}t[maxn], a[maxn], b[maxn];
int root, tcnt = 0;
In void pushup(int now)
{
for(int i = 0; i < 2; ++i)
{
if(t[now].ch[0])
{
t[now].Max[i] = max(t[now].Max[i], t[t[now].ch[0]].Max[i]);
t[now].Min[i] = min(t[now].Min[i], t[t[now].ch[0]].Min[i]);
}
if(t[now].ch[1])
{
t[now].Max[i] = max(t[now].Max[i], t[t[now].ch[1]].Max[i]);
t[now].Min[i] = min(t[now].Min[i], t[t[now].ch[1]].Min[i]);
}
}
}
In void build(int& now, int L, int R, int d)
{
if(L > R) return;
int mid = (L + R) >> 1;
Dim = d;
nth_element(a + L, a + mid, a + R + 1);
t[now = ++tcnt] = a[mid];
t[now].ch[0] = t[now].ch[1] = 0; t[now].id = a[mid].id;
t[now].Min[0] = t[now].Max[0] = t[now].d[0];
t[now].Min[1] = t[now].Max[1] = t[now].d[1];
build(t[now].ch[0], L, mid - 1, d ^ 1);
build(t[now].ch[1], mid + 1, R, d ^ 1);
pushup(now);
}
In ll dis(int now, ll* d)
{
return abs(t[now].d[0] - d[0]) + abs(t[now].d[1] - d[1]);
}
In ll price_Max(int now, ll* d)
{
ll ret = 0;
for(int i = 0; i < 2; ++i)
{
ll Max = max(abs(t[now].Max[i] - d[i]), abs(t[now].Min[i] - d[i]));
ret += Max;
}
return ret;
}
In ll price_Min(int now, ll * d)
{
ll ret = 0;
for(int i = 0; i < 2; ++i)
if(t[now].Min[i] > d[i]) ret += t[now].Min[i] - d[i];
else if(t[now].Max[i] < d[i]) ret += d[i] - t[now].Max[i];
return ret;
}
ll Max = -1, Min = INF;
In void query_Max(int now, ll* d, int id)
{
if(!now) return;
if(t[now].id ^ id) Max = max(Max, dis(now, d));
ll disL = price_Max(t[now].ch[0], d), disR = price_Max(t[now].ch[1], d);
if(disL < disR) swap(disL, disR), swap(t[now].ch[0], t[now].ch[1]);
if(disL > Max) query_Max(t[now].ch[0], d, id);
if(disR > Max) query_Max(t[now].ch[1], d, id);
}
In void query_Min(int now, ll* d, int id)
{
if(!now) return;
if(t[now].id ^ id) Min = min(Min, dis(now, d));
ll disL = price_Min(t[now].ch[0], d), disR = price_Min(t[now].ch[1], d);
if(disL > disR) swap(disL, disR), swap(t[now].ch[0], t[now].ch[1]);
if(disL < Min) query_Min(t[now].ch[0], d, id);
if(disR < Min) query_Min(t[now].ch[1], d, id);
} int main()
{
n = read();
for(int i = 1; i <= n; ++i) a[i].d[0] = read(), a[i].d[1] = read(), a[i].id = i, b[i] = a[i];
build(root, 1, n, 0);
ll ans = INF;
for(int i = 1; i <= n; ++i)
{
Min = INF, Max = -1;
query_Max(root, b[i].d, i); query_Min(root, b[i].d, i);
ans = min(ans, Max - Min);
}
write(ans), enter;
return 0;
}

[SDOI2010]捉迷藏的更多相关文章

  1. [SDOI2010]捉迷藏 K-Dtree

    [SDOI2010]捉迷藏 链接 luogu 思路 k-dtree模板题 代码 #include <bits/stdc++.h> #define ls (t[u].ch[0]) #defi ...

  2. luoguP2479 [SDOI2010]捉迷藏

    https://www.luogu.org/problemnew/show/P2479 据说可以用线段树做但是我不会,只能写一个 KD-Tree 了 对于每个点求出距离它最远的点和最近的点的距离,然后 ...

  3. P2479 [SDOI2010]捉迷藏

    传送门 KDtree是个吼东西啊-- 枚举每一个点,然后求出离他距离最远和最近的点的距离,更新答案 然而为什么感觉KDtree只是因为剪枝才能跑得动呢-- //minamoto #include< ...

  4. 模板—K-D-tree(P2479 [SDOI2010]捉迷藏)

    #include<algorithm> #include<iostream> #include<cstdio> #include<cmath> #def ...

  5. 【题解】[SDOI2010]捉迷藏

    题目链接:https://www.luogu.com.cn/problem/P2479 题目大意:求平面\(n\)个点中,到其它\(n-1\)个点的曼哈顿距离最大和最小距离之差最小的点,求出这个这个距 ...

  6. [学习笔记]K-D Tree

    以前其实学过的但是不会拍扁重构--所以这几天学了一下 \(K-D\ Tree\) 的正确打开姿势. \(K\) 维 \(K-D\ Tree\) 的单次操作最坏时间复杂度为 \(O(k\times n^ ...

  7. KD-Tree总结

    KD-Tree总结 问题引入 平面上有\(n\)个点,\(q\)组询问,每一次查询距离\((x,y)\)最近的点对,强制在线. 问题解决 暴力 显然我们可以直接枚举点然后算距离取\(min\),这样子 ...

  8. 2021.07.09 K-D树

    2021.07.09 K-D树 前置知识 1.二叉搜索树 2.总是很长的替罪羊树 K-D树 建树 K-D树具有二叉搜索树的形态,对于每一个分类标准,小于标准的节点在父节点左边,大于标准的节点在父节点右 ...

  9. [BZOJ1941][Sdoi2010]Hide and Seek

    [BZOJ1941][Sdoi2010]Hide and Seek 试题描述 小猪iPig在PKU刚上完了无聊的猪性代数课,天资聪慧的iPig被这门对他来说无比简单的课弄得非常寂寞,为了消除寂寞感,他 ...

随机推荐

  1. PHP 网页数据api采集

    一个简单的数据采集,这里用的方法是API数据采集 //api地址,读取文本 $result = file_get_contents("https://feed.mix.sina.com.cn ...

  2. Cassandra 数据模型

    Cassandra的数据模型类似于关系型数据库的模型,且提供了与SQL语言非常类似的CQL语言进行操作. 但是Cassandra的数据模型类似于多层键值对结构,与关系型数据库存在巨大差别. 本文基于: ...

  3. [PHP]算法- 判断是否为二叉搜索树的后序遍历序列的PHP实现

    二叉搜索树的后序遍历序列: 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则输出Yes,否则输出No.假设输入的数组的任意两个数字都互不相同. 思路: 1.后序遍历是 左右中 ...

  4. 【RabbitMQ】6、rabbitmq生产者的消息确认

    通过Publisher Confirms and Returns机制,生产者可以判断消息是否发送到了exchange及queue,而通过消费者确认机制,Rabbitmq可以决定是否重发消息给消费者,以 ...

  5. 【开发工具之eclipse】7、eclipse代码自动提示,eclipse设置代码自动提示

    首先打开Eclipse开发软件,然后在工具栏的[Window],点击后找到弹出列表中的[Preferences]选项,然后点击这个选项   现在弹出的窗口就是JAVA开发人员常见的设置窗口了,我们依次 ...

  6. Ajax实现的城市二级联动三

    把之前2篇整合在一起 1.html <select id="province"> <option>请选择</option> </selec ...

  7. 手把手教你实现Confluence6.7.1安装与破解

    Confluence是一个专业的企业知识管理与协同软件,也可以用于构建企业wiki. 一.准备工作 下载confluence6.7.1 wget https://downloads.atlassian ...

  8. SP8093 JZPGYZ - Sevenk Love Oimaster(广义后缀自动机)

    题意 题目链接 Sol 广义后缀自动机板子题..和BZOJ串那个题很像 首先建出询问串的SAM,然后统计一下每个节点被多少个串包含 最后直接拿询问串上去跑就行了 #include<bits/st ...

  9. Mybatis PageHelper 简单使用

    流程 1,maven 依赖 2,在 mybatis 配置文件启用插件 3,修改 service 层 依赖 <!-- https://mvnrepository.com/artifact/com. ...

  10. 惊闻企业Web应用生成平台 活字格 V4.0 免费了,不单可视化设计器免费,服务器也免费!

    官网消息: 针对活字格开发者,新版本完全免费!您可下载活字格 Web 应用生成平台 V4.0 Updated 1,方便的创建各类 Web 应用系统,任意部署,永不过期. 我之前学习过活字格,也曾经向用 ...