K-D Tree 裸题，有插入操作。

``` #include <cstdio>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <algorithm>

using namespace std;

const int inf = 1e9;
;
+ ;

;
char ch = getchar();

') ch = getchar();
') {
x = x *  + ch - ';
ch = getchar();
}
return x;
}

int n, m, root, D, ans;

struct Node {
int d[K], mn[K], mx[K], l, r, v, sum;

int & operator [] (int x) {
return d[x];
}
Node(, ) {
l = ; r = ; d[] = x; d[] = y;
}
friend bool operator < (Node a, Node b) {
return a[D] < b[D];
}
}p[N], T[N<<], tmp;

void pushup(int k) {
Node l = T[T[k].l], r = T[T[k].r];

; i < K; ++ i) {
T[k].mn[i] = T[k].mx[i] = T[k][i];
if(T[k].l) {
T[k].mn[i] = min(T[k].mn[i], l.mn[i]);
T[k].mx[i] = max(T[k].mx[i], l.mx[i]);
}
if(T[k].r) {
T[k].mx[i] = max(T[k].mx[i], r.mx[i]);
T[k].mn[i] = min(T[k].mn[i], r.mn[i]);
}
}
//  T[k].sum = T[k].v;
//  if(T[k].l) T[k].sum += l.sum;
//  if(T[k].r) T[k].sum += r.sum;
}

int build(int l, int r, int nd) {
;

D = nd;
nth_element(p + l, p + mid, p + r + );
T[mid] = p[mid];
T[mid].l = T[mid].r = ;
; i < K; ++ i)
T[mid].mx[i] = T[mid].mn[i] = T[mid][i];
if(l < mid)
T[mid].l = build(l, mid - , (nd + ) % K);
if(r > mid)
T[mid].r = build(mid + , r, (nd + ) % K);
pushup(mid);
return mid;
}

void insert(int k, int nd) {
if(tmp[nd] >= T[k][nd]) {
) % K);
else {
T[k].r = ++ n;
T[n] = tmp;
; i < K; ++ i)
T[n].mn[i] = T[n].mx[i] = T[n][i];
}
}
else {
) % K);
else {
T[k].l = ++ n;
T[n] = tmp;
; i < K; ++ i)
T[n].mn[i] = T[n].mx[i] = T[n][i];
}
}
pushup(k);
}

int getkdis(Node a, Node b) {
;

; i < K; ++ i)
res += abs(a[i] - b[i]);
return res;
}

int inandout(int k, Node a) {
;

; i < K; ++ i)
res += max(, T[k].mn[i] - a[i]);
; i < K; ++ i)
res += max(, a[i] - T[k].mx[i]);
return res;
}

void query(int k, int nd) {
int d, dl = inf, dr = inf;

d = getkdis(T[k], tmp);
if(d) ans = min(ans, d);
if(T[k].l) dl = inandout(T[k].l, tmp);
if(T[k].r) dr = inandout(T[k].r, tmp);
if(dl < dr) {
) % K);
) % K);
}
else {
) % K);
) % K);
}
}

int query(Node a) {
tmp = a; ans = inf;
query(root, );
return ans;
}

void insert(Node a) {
tmp = a; insert(root, );
}
#define ONLINE_JUDGE
int main() {
#ifndef ONLINE_JUDGE
freopen("1.in", "r", stdin);
freopen("1.out", "w", stdout);
#endif

int type, x, y;

; i <= n; ++ i)
root = build(, n, );//忘记写root等于了。
; i <= m; ++ i) {
) insert(Node(x, y));
else printf("%d\n", query(Node(x, y)));
}

#ifndef ONLINE_JUDGE
fclose(stdin); fclose(stdout);
#endif
;
}```

BZOJ 2716

K-D Tree裸题，注意最近点不能是自己。

``` #include <cstdio>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <algorithm>

using namespace std;

+ ;
const int inf = 1e9;
;

;
char ch = getchar();

') ch = getchar();
') {
x = x *  + ch - ';
ch = getchar();
}
return x;
}

int n, root, amax, amin, D;

struct Node {
int d[K], mn[K], mx[K], l, r;

int & operator [] (int x) {
return d[x];
}
Node (, ) {
l = ; r = ; d[] = x; d[] = y;
}
friend bool operator < (Node a, Node b) {
return a[D] < b[D];
}
}p[N], T[N<<], tmp;

void pushup(int k) {
Node l = T[T[k].l], r = T[T[k].r];

; i < K; ++ i) {
T[k].mn[i] = T[k].mx[i] = T[k][i];
if(T[k].l) {
T[k].mx[i] = max(T[k].mx[i], l.mx[i]);
T[k].mn[i] = min(T[k].mn[i], l.mn[i]);
}
if(T[k].r) {
T[k].mx[i] = max(T[k].mx[i], r.mx[i]);
T[k].mn[i] = min(T[k].mn[i], r.mn[i]);
}
}
}

int build(int l, int r, int nd) {
;

D = nd;
nth_element(p + l, p + mid, p + r + );
T[mid] = p[mid];
T[mid].l = T[mid].r = ;
; i < K; ++ i)
T[mid].mn[i] = T[mid].mx[i] = T[mid][i];
, (D + ) % K);
, r, (D + ) % K);
pushup(mid);
return mid;
}

void insert(int k, int nd) {
if(tmp[nd] >= T[k][nd]) {
) % K);
else {
T[k].r = ++ n;
T[n] = tmp;
; i < K; ++ i)
T[n].mx[i] = T[n].mn[i] = T[n][i];
}
}
else {
) % K);
else {
T[k].l = ++ n;
T[n] = tmp;
; i < K; ++ i)
T[n].mx[i] = T[n].mn[i] = T[n][i];
}
}
pushup(k);
}

int getkdis(Node a, Node b) {
;

; i < K; ++ i)
res += abs(a[i] - b[i]);
return res;
}

int outandin(int k, Node q) {
;

; i < K; ++ i)
res += max(, T[k].mn[i] - q[i]);
; i < K; ++ i)
res += max(, q[i] - T[k].mx[i]);
return res;
}

int outandinmaxx(int k, Node q) {
;

; i < K; ++ i)
res += max(abs(T[k].mn[i] - q[i]), abs(T[k].mx[i] - q[i]));
return res;
}

void query_maxx(int k, int nd) {
int d, dl = -inf, dr = -inf;

d = getkdis(T[k], tmp);
amax = max(d, amax);
if(T[k].l) dl = outandinmaxx(T[k].l, tmp);
if(T[k].r) dr = outandinmaxx(T[k].r, tmp);
if(dl > dr) {
) % K);
) % K);
}
else {
) % K);
) % K);
}
}

void query_minn(int k, int nd) {
int d, dl = inf, dr = inf;

d = getkdis(T[k], tmp);
if(d) amin = min(d, amin);
if(T[k].l) dl = outandin(T[k].l, tmp);
if(T[k].r) dr = outandin(T[k].r, tmp);
if(dl < dr) {
) % K);
) % K);
}
else {
) % K);
) % K);
}
}

void qmax(int l) {
amax = -inf; tmp = p[l];
query_maxx(root, );

}

void qmin(int l) {
amin = inf; tmp = p[l];
query_minn(root, );
}

int main() {
int outans = inf;

; i <= n; ++ i) {
}
root = build(, n, );
; i <= n; ++ i) {
qmax(i); qmin(i);
outans = min(outans, amax - amin);
}
printf("%d\n", outans);
;
}```

BZOJ 1941

1、为了防止重复，小根堆里面保存2*K个元素。

2、编程习惯一定要好。同类型比较，减少强制类型转制。在查询欧几里德距离的时候，query中的维度参数是没有用的。

```#include <cstdlib>
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cctype>
#include <queue>
#include <vector>

using namespace std;
typedef long long ll;
const int N = 100000 + 5;
const int K = 2;
const ll inf = 10000000000000LL;
int x = 0; char c = getchar();
while(!isdigit(c)) c = getchar();
while(isdigit(c)) {
x = x * 10 + c - '0';
c = getchar();
}
return x;
}
int buf[20];
inline void output(ll x) {
int p = 0; buf[0] = 0;
if(!x) p ++;
else {
while(x) {
buf[p ++] = x % 10;
x /= 10;
}
}
for(int i = p - 1; i >= 0; -- i)
putchar(buf[i] + '0');
}

int root, n, kk, D;
priority_queue <ll, vector<ll>, greater<ll> > ans;

struct Node {
int l, r;
ll d[K], mn[K], mx[K];
Node(ll x = 0, ll y = 0) {
l = r = 0; d[0] = x; d[1] = y;
}
ll & operator [] (int x) { return d[x];}
friend bool operator < (Node a, Node b) {
return a[D] < b[D];
}
}p[N], T[N << 1], tmp;

void pushup(int k) {
Node l = T[T[k].l], r = T[T[k].r];
for(int i = 0; i < K; ++ i) {
T[k].mx[i] = T[k].mn[i] = T[k][i];
if(T[k].l) {
T[k].mx[i] = max(T[k].mx[i], l.mx[i]);
T[k].mn[i] = min(T[k].mn[i], l.mn[i]);
}
if(T[k].r) {
T[k].mx[i] = max(T[k].mx[i], r.mx[i]);
T[k].mn[i] = min(T[k].mn[i], r.mn[i]);
}
}
}

int build(int l, int r, int nd) {
int mid = (l + r) >> 1;
D = nd;
nth_element(p + l, p + mid, p + r + 1);
T[mid] = p[mid];
T[mid].l = T[mid].r = 0;
for(int i = 0; i < K; ++ i)
T[mid].mx[i] = T[mid].mn[i] = T[mid][i];
if(l < mid) T[mid].l = build(l, mid - 1, (nd + 1) % K);
if(r > mid) T[mid].r = build(mid + 1, r, (nd + 1) % K);
pushup(mid);
return mid;
}

ll geteulerdis(Node a, Node b) {//竭诚为欧几里德距离服务
ll res = 0;
for(int i = 0; i < K; ++ i)
res += (a[i] - b[i]) * (a[i] - b[i]);
return res;
}

ll outandineuler(Node a) {
ll L = 0;
L = max(L, geteulerdis(tmp, Node(a.mx[0], a.mn[1])));
L = max(L, geteulerdis(tmp, Node(a.mx[0], a.mx[1])));
L = max(L, geteulerdis(tmp, Node(a.mn[0], a.mn[1])));
L = max(L, geteulerdis(tmp, Node(a.mn[0], a.mx[1])));
return L;
}

void query(int k) {
ll d, dl = -inf, dr = -inf;
d = geteulerdis(T[k], tmp);
if(d > ans.top()) {
ans.pop(); ans.push(d);
}
if(T[k].l) dl = outandineuler(T[T[k].l]);
if(T[k].r) dr = outandineuler(T[T[k].r]);
if(dl > dr) {
if(dl > ans.top()) query(T[k].l);
if(dr > ans.top()) query(T[k].r);
}
else {
if(dr > ans.top()) query(T[k].r);
if(dl > ans.top()) query(T[k].l);
}
}

void Q(int i) {
tmp = p[i];
query(root);
}

int main() {
for(int i = 1; i <= 2 * kk; ++ i) ans.push(0);
for(int i = 1; i <= n; ++ i) {
}
root = build(1, n, 0);
for(int i = 1; i <= n; ++ i) Q(i);
output(ans.top());
return 0;
}
```

## K-D Tree题目泛做（CXJ第二轮）的更多相关文章

题目1: SPOJ 2832 题目大意: 求一个矩阵行列式模一个数P后的值.p不一定是质数. 算法讨论: 因为有除法而且p不一定是质数,不一定有逆元,所以我们用辗转相除法. #include < ...

题目1: NOI2014 魔法森林 LCT维护MST.解题报告见LOFTER #include <cstdio> #include <iostream> #include &l ...

3. FFT与多项式、生成函数题目泛做

题目1 COGS 很强的乘法问题 高精度乘法用FFT加速 #include <cstdlib> #include <iostream> #include <algorit ...

4. 二维计算几何基础题目泛做（SYX第一轮）

题目1: POJ 2318 TOYS 题目大意: 给一个有n个挡板的盒子,从左到右空格编号为0...n.有好多玩具,问每个玩具在哪个空格里面. 算法讨论: 直接叉积判断就可以.注意在盒子的边界上面也算 ...

5. 后缀自动机/回文自动机/AC自动机/序列自动机----各种自动机(自冻鸡) 题目泛做

题目1 BZOJ 3676 APIO2014 回文串 算法讨论: cnt表示回文自动机上每个结点回文串出现的次数.这是回文自动机的定义考查题. #include <cstdlib> #in ...

题目1:BZOJ 2049 洞穴勘测 #include <bits/stdc++.h> #define L(x) c[x][0] #define R(x) c[x][1] using na ...

7. 插头DP题目泛做（为了对应WYD的课件）

题目1:BZOJ 1814 URAL 1519 Formula 1 题目大意:给定一个N*M的棋盘,上面有障碍格子.求一个经过所有非障碍格子形成的回路的数量. 插头DP入门题.记录连通分量. #inc ...

题1: Uva 1636 Headshot 题目大意: 给出一个000111序列,注意实际上是环状的.问是0出现的概率大,还是当前是0,下一个还是0的概率大. 问题比较简单,注意比较大小: A/C & ...

9. 莫比乌斯反演题目泛做（为了对应smz的课件）

题1:BZOJ2190 SDOI 2010 仪仗队 题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2190 算法讨论: 我们先来考虑一个点被 ...

## 随机推荐

1. Datazen安装

Datazen是被微软收购的移动端全平台的数据展现解决方案.此篇主要介绍其安装过程. 下载页面,需要留意一下的是目前还没有中文版: http://www.datazen.com/start/ 点击Do ...

2. [翻译svg教程]svg中矩形元素 rect

svg 元素<rect> 是一个矩形元素,用这个元素,可以你可以绘制矩形,设置矩形宽高,边框的宽度颜色,矩形的填充颜色,是否用圆角等 rect 示例 <svg xmlns=" ...

3. codeforces 练习

codeforces 627 D. Preorder Test 二分 + 树dp 做logn次树dp codeforces 578D.LCS Again 给出一个字符串str,长度n<=10^6 ...

4. OPTIMIZE TABLE 小解

首先看一下语法:  OPTIMIZE [NO_WRITE_TO_BINLOG | LOCAL] TABLE tbl_name [, tbl_name] ... 我们知道mysql存储引擎里面的数据和索 ...

5. xcode运行push通知总是提示输入用户名和密码

xcode运行push通知总是提示输入用户名和密码,目前找到的解决方案是,  打开钥匙串,然后找到push证书下面的私有密钥,双击进入将访问控制设置为允许全部访问,即可.

6. 使用Universal USB Installer安装Ubuntu

1.下载Universal USB Installer 下载地址: 2.下载ubuntu 14 desktop.iso 运行Universal USB Installer,找到电脑上 ubuntu 1 ...

7. UIButton的常见设置

- (void)setTitle:(NSString *)title forState:(UIControlState)state;设置按钮的文字 - (void)setTitleColor:(UIC ...

8. [译]Quartz 框架 教程（中文版）2.2.x 之第一课 开始使用Quartz框架

第一课:开始使用Quartz框架 在你使用调度器之前,需要借助一些具体的例子去理解(谁愿意只是猜啊?).你可以使用SchedulerFactory类来达到程序调度的目的.有一些Quartz框架的用户可 ...

9. centos6.7 本地yum源配置

[BEGIN] 2016/11/9 21:47:31[root@11g ~]# mount /dev/cdrom /mediamount: block device /dev/sr0 is write ...

10. 在Windows下Mysql如何重置root用户密码