bzoj2648
http://www.lydsy.com/JudgeOnline/problem.php?id=2648
kdtree裸题。。。
抄板子一边抄对了。。。
挺好理解的,就是说我们先找出中间的元素,然后小的放左边,大的放右边,这样我们就确定了这个点,然后维度换一下,递归建树,很像splay,其实就是把平面每次一分为二,先横着再竖着。。。
然后那个get挺神奇的,大概就是估计一下现在这个点距离下一个区域的距离?其实就是优化枚举,减少了很多重复状态。。。
#include<bits/stdc++.h>
using namespace std;
const int N = , inf = << ;
struct data {
int l, r, d[], min[], max[];
} t[N];
int n, m, root, ans, d;
bool cp(data x, data y)
{
if(x.d[d] != y.d[d]) return x.d[d] < y.d[d];
return x.d[d ^ ] < y.d[d ^ ];
}
void update(int k)
{
for(int i = ; i < ; ++i)
{
if(t[k].l) t[k].min[i] = min(t[k].min[i], t[t[k].l].min[i]), t[k].max[i] = max(t[k].max[i], t[t[k].l].max[i]);
if(t[k].r) t[k].min[i] = min(t[k].min[i], t[t[k].r].min[i]), t[k].max[i] = max(t[k].max[i], t[t[k].r].max[i]);
}
}
int get(int k, data x)
{
int ret = ;
for(int i = ; i < ; ++i) ret += max(t[k].min[i] - x.d[i], ) + max(x.d[i] - t[k].max[i], );
return ret;
}
int build(int l, int r, int now)
{
d = now;
int mid = (l + r) >> ;
nth_element(t + l + , t + mid + , t + r + , cp);
for(int i = ; i < ; ++i) t[mid].min[i] = t[mid].max[i] = t[mid].d[i];
if(l < mid) t[mid].l = build(l, mid - , now ^ );
if(r > mid) t[mid].r = build(mid + , r, now ^ );
update(mid); return mid;
}
void insert(int k, int now, data x)
{
if(x.d[now] < t[k].d[now])
{
if(t[k].l) insert(t[k].l, now ^ , x);
else
{
t[k].l = ++n;
for(int i = ; i < ; ++i) t[n].max[i] = t[n].min[i] = t[n].d[i] = x.d[i];
}
}
else
{
if(t[k].r) insert(t[k].r, now ^ , x);
else
{
t[k].r = ++n;
for(int i = ; i < ; ++i) t[n].max[i] = t[n].min[i] = t[n].d[i] = x.d[i];
}
}
update(k);
}
void query(int k, int now, data x)
{
int d = abs(t[k].d[] - x.d[]) + abs(t[k].d[] - x.d[]), dl = inf, dr = inf;
ans = min(ans, d);
if(t[k].l) dl = get(t[k].l, x);
if(t[k].r) dr = get(t[k].r, x);
if(dl < dr)
{
if(dl < ans) query(t[k].l, now ^ , x);
if(dr < ans) query(t[k].r, now ^ , x);
}
else
{
if(dr < ans) query(t[k].r, now ^ , x);
if(dl < ans) query(t[k].l, now ^ , x);
}
}
int main()
{
scanf("%d%d", &n, &m);
for(int i = ; i <= n; ++i) scanf("%d%d", &t[i].d[], &t[i].d[]);
root = build(, n, );
while(m--)
{
int opt; data x; scanf("%d%d%d", &opt, &x.d[], &x.d[]);
if(opt == ) insert(root, , x);
if(opt == )
{
ans = inf;
query(root, , x);
printf("%d\n", ans);
}
}
return ;
}
bzoj2648的更多相关文章
- 【bzoj2648】 SJY摆棋子
http://www.lydsy.com/JudgeOnline/problem.php?id=2648 (题目链接) 题意 动态维护二维平面上的点的插入以及最邻近域搜索. Solution KDtr ...
- BZOJ2648 SJY摆棋子(KD-Tree)
板子题. #include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> # ...
- 【BZOJ2648】SJY摆棋子(KD-Tree)
[BZOJ2648]SJY摆棋子(KD-Tree) 题面 BZOJ Description 这天,SJY显得无聊.在家自己玩.在一个棋盘上,有N个黑色棋子.他每次要么放到棋盘上一个黑色棋子,要么放上一 ...
- BZOJ2648: SJY摆棋子&&2716: [Violet 3]天使玩偶
BZOJ2648: SJY摆棋子 BZOJ2716: [Violet 3]天使玩偶 BZOJ氪金无极限... 其实这两道是同一题. 附上2648的题面: Description 这天,SJY显得无聊. ...
- 【BZOJ2648】SJY摆棋子 KDtree
[BZOJ2648]SJY摆棋子 Description 这天,SJY显得无聊.在家自己玩.在一个棋盘上,有N个黑色棋子.他每次要么放到棋盘上一个黑色棋子,要么放上一个白色棋子,如果是白色棋子,他会找 ...
- KD-Tree复习笔记(BZOJ1941 & BZOJ2648 & BZOJ4066)
快一年了都没碰到什么必须用KDT的题目导致模板完全忘光了,重新复习了一下. K_Dimention_Tree是一种用来处理二维以上问题的数据结构(OI中一般都是二维),本质是二维启发式估价函数实现剪枝 ...
- [bzoj2648/2716]SJY摆棋子_KD-Tree
SJY摆旗子 bzoj-2648 题目大意:平面上有n个黑子.有m个操作,可以下一颗白子,查询与曼哈顿距离下最近黑子之间的曼哈顿距离,或者下一颗黑子. 注释:$1\le n,m\le 5\cdot 1 ...
- 【BZOJ-2648&2716】SJY摆棋子&天使玩偶 KD Tree
2648: SJY摆棋子 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 2459 Solved: 834[Submit][Status][Discu ...
- Bzoj2648 SJY摆棋子
Time Limit: 20 Sec Memory Limit: 128 MB Submit: 3128 Solved: 1067 Description 这天,SJY显得无聊.在家自己玩.在一个 ...
- 【kd-tree】bzoj2648 SJY摆棋子
#include<cstdio> #include<cmath> #include<algorithm> using namespace std; #define ...
随机推荐
- ThinkPHP---TP功能类之上传
[一]概论 (1)上传操作的核心操作:移动临时文件(move_upload_file),在ThinkPHP里封装了上传类Upload.class.php (2)上传类Upload.class.php代 ...
- 抓取猫眼电影top100的正则、bs4、pyquery、xpath实现方法
import requests import re import json import time from bs4 import BeautifulSoup from pyquery import ...
- 并查集(Union Find)的基本实现
概念 并查集是一种树形的数据结构,用来处理一些不交集的合并及查询问题.主要有两个操作: find:确定元素属于哪一个子集. union:将两个子集合并成同一个集合. 所以并查集能够解决网络中节点的连通 ...
- 浅谈es6 promise
本文是借鉴于ac黄的博客. 接触es6也有几个月了,貌似没有系统的去学习过它,总是用到什么,查查什么.今天就说下es6中的promise对象. 先说说promise解决了什么问题? 写前端的同学都经常 ...
- 每日命令:(2)cd
Linux cd 命令可以说是Linux中最基本的命令语句,其他的命令语句要进行操作,都是建立在使用 cd 命令上的. 所以,学习Linux 常用命令,首先就要学好 cd 命令的使用方法技巧. 1. ...
- python实现字符串转换整数
实现一个函数,使其能将字符串转换成整数. 首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止. 当我们寻找到的第一个非空字符为正或者负号时,则将该符号与之后面尽可能多的连续 ...
- Spring MVC概述(2)
1.Spring 为展现层提供基于MVC设计理念的优秀的Web框架,是目前最主流的MVC框架之一. 2.Spring 3.0后全面超越Struts2,成为最优秀的MVC框架. 3.Spring MVC ...
- Android NumberProgressBar:动态移动显示百分比进度的进度条
Android NumberProgressBar:动态移动显示百分比进度的进度条 NumberProgressBar是github上一个开源项目,其项目主页是:https://github.c ...
- 自己修改的vim配色选择器的颜色显示部分
话不多说,上代码如下: " ___ __) ) ___ ______) " (, |/ (__/_____) /) (, / /) /) " | _/_ _ __ ___ ...
- Ubuntu 16.04下MySQL 5.7.18取消开机启动(解决无法使用Sysvinit(update-rc.d/sysv-rc-conf)脚本关闭)
首先了解以下运行级别对应工具的变化历史: 1.Ubuntu 6.10及以前版本使用Sysvinit. 2.Ubuntu 14.10及以前版本使用Upstart但是还留着Sysvinit并存. http ...