嘟嘟嘟




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. Lucene实战之关键字匹配多个字段

    前言 当我们输入关键字时希望可以支持筛选多个字段,这样搜索内容的覆盖率就会大一些. 匹配多个字段主要用 MultiFieldQueryParser类. 单一字段搜索 QueryParser parse ...

  2. MySQLdump之single-transaction详解

    MySQLdump之single-transaction详解 single-transaction 开启general log选项 查看目前general log的情况 mysql> show ...

  3. IdentityServer4 中文文档 -10- (快速入门)使用密码保护API

    IdentityServer4 中文文档 -10- (快速入门)使用密码保护API 原文:http://docs.identityserver.io/en/release/quickstarts/2_ ...

  4. 钉钉接口:获取accessToken和打卡记录【分享】

    post和get方法工具类:HttpUtils package weaver.dingtalk.utils; import com.alibaba.fastjson.JSONObject; impor ...

  5. 随机漂浮图片、右侧上下浮动快捷栏JS

    随机漂浮图片JS: //公共脚本文件 main.js function addEvent(obj,evtType,func,cap){ cap=cap||false; if(obj.addEventL ...

  6. Java基础——Oracle(四)

    一.Sql * plus 常用命令 1.关于登录,连接的几个命令 1) conn[nect] //例  conn system/manager 用法 conn 用户名/密码 @网络服务名 (as sy ...

  7. ajax小知识

    1.ajax发送get请求时,需要注意如下情况: var uri="http://127.0.0.1:8071/springmvcdemo/bigdataapi/publishdata&qu ...

  8. map标签

    map和area 标签配合img标签制作分区超链接效果 http://www.w3school.com.cn/tiy/t.asp?f=html_areamap

  9. Vue Router滚动行为 scrollBehavior

    滚动行为 使用前端路由,当切换到新路由时,想要页面滚动到顶部或者是保持原先的滚动位置,就像重新加载页面那样. vue-router能做到,而且更好,它让你可以自定义路由切换时页面如何滚动. 注意:这个 ...

  10. Android studio 在一个项目上添加另一个项目,引用其内部参数

    Setting.gradle 里面 添加 include ':app',‘imagePicker’ 其中 imagePicker 为要引入的项目名 build.gradle(Module: app)  ...