题目1: BZOJ 2716

题目大意:给出N个二维平面上的点,M个操作,分为插入一个新点和询问到一个点最近点的Manhatan距离是多少。

算法讨论:

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

 #include <cstdio>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <algorithm> using namespace std; const int inf = 1e9;
const int K = ;
const int N = + ; inline int read() {
int x = ;
char ch = getchar(); while(ch < '' || ch > '') ch = getchar();
while(ch <= '' && ch >= '') {
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(int x = , int y = ) {
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]; for(int i = ; 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) {
int mid = (l + r) >> ; D = nd;
nth_element(p + l, p + mid, p + r + );
T[mid] = p[mid];
T[mid].l = T[mid].r = ;
for(int i = ; 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]) {
if(T[k].r) insert(T[k].r, (nd + ) % K);
else {
T[k].r = ++ n;
T[n] = tmp;
for(int i = ; i < K; ++ i)
T[n].mn[i] = T[n].mx[i] = T[n][i];
}
}
else {
if(T[k].l) insert(T[k].l, (nd + ) % K);
else {
T[k].l = ++ n;
T[n] = tmp;
for(int i = ; i < K; ++ i)
T[n].mn[i] = T[n].mx[i] = T[n][i];
}
}
pushup(k);
} int getkdis(Node a, Node b) {
int res = ; for(int i = ; i < K; ++ i)
res += abs(a[i] - b[i]);
return res;
} int inandout(int k, Node a) {
int res = ; for(int i = ; i < K; ++ i)
res += max(, T[k].mn[i] - a[i]);
for(int 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) {
if(dl < ans) query(T[k].l, (nd + ) % K);
if(dr < ans) query(T[k].r, (nd + ) % K);
}
else {
if(dr < ans) query(T[k].r, (nd + ) % K);
if(dl < ans) query(T[k].l, (nd + ) % 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; n = read(); m = read();
for(int i = ; i <= n; ++ i)
p[i][] = read(), p[i][] = read();
root = build(, n, );//忘记写root等于了。
for(int i = ; i <= m; ++ i) {
type = read(); x = read(); y = read();
if(type == ) insert(Node(x, y));
else printf("%d\n", query(Node(x, y)));
} #ifndef ONLINE_JUDGE
fclose(stdin); fclose(stdout);
#endif
return ;
}

BZOJ 2716

题目2: BZOJ 1941

题目大意:给出N个点,求对于每个点说,Manhantan距离最远点与最近点的差值最小是多少。

算法讨论:

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

 #include <cstdio>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <algorithm> using namespace std; const int N = + ;
const int inf = 1e9;
const int K = ; inline int read() {
int x = ;
char ch = getchar(); while(ch < '' || ch > '') ch = getchar();
while(ch <= '' && ch >= '') {
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 (int x = , int y = ) {
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]; for(int i = ; 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) {
int mid = (l + r) >> ; D = nd;
nth_element(p + l, p + mid, p + r + );
T[mid] = p[mid];
T[mid].l = T[mid].r = ;
for(int i = ; i < K; ++ i)
T[mid].mn[i] = T[mid].mx[i] = T[mid][i];
if(l < mid) T[mid].l = build(l, mid - , (D + ) % K);
if(r > mid) T[mid].r = build(mid + , r, (D + ) % K);
pushup(mid);
return mid;
} void insert(int k, int nd) {
if(tmp[nd] >= T[k][nd]) {
if(T[k].r) insert(T[k].r, (nd + ) % K);
else {
T[k].r = ++ n;
T[n] = tmp;
for(int i = ; i < K; ++ i)
T[n].mx[i] = T[n].mn[i] = T[n][i];
}
}
else {
if(T[k].l) insert(T[k].l, (nd + ) % K);
else {
T[k].l = ++ n;
T[n] = tmp;
for(int i = ; i < K; ++ i)
T[n].mx[i] = T[n].mn[i] = T[n][i];
}
}
pushup(k);
} int getkdis(Node a, Node b) {
int res = ; for(int i = ; i < K; ++ i)
res += abs(a[i] - b[i]);
return res;
} int outandin(int k, Node q) {
int res = ; for(int i = ; i < K; ++ i)
res += max(, T[k].mn[i] - q[i]);
for(int i = ; i < K; ++ i)
res += max(, q[i] - T[k].mx[i]);
return res;
} int outandinmaxx(int k, Node q) {
int res = ; for(int i = ; 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) {
if(dl > amax) query_maxx(T[k].l, (nd + ) % K);
if(dr > amax) query_maxx(T[k].r, (nd + ) % K);
}
else {
if(dr > amax) query_maxx(T[k].r, (nd + ) % K);
if(dl > amax) query_maxx(T[k].l, (nd + ) % 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) {
if(dl < amin) query_minn(T[k].l, (nd + ) % K);
if(dr < amin) query_minn(T[k].r, (nd + ) % K);
}
else {
if(dr < amin) query_minn(T[k].r, (nd + ) % K);
if(dl < amin) query_minn(T[k].l, (nd + ) % 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; n = read();
for(int i = ; i <= n; ++ i) {
p[i][] = read(); p[i][] = read();
}
root = build(, n, );
for(int i = ; i <= n; ++ i) {
qmax(i); qmin(i);
outans = min(outans, amax - amin);
}
printf("%d\n", outans);
return ;
}

BZOJ 1941

题目3: BZOJ4520 && CQOI 2016 K远点对查询

题目大意:

给出n个二维平面上的点,求第k远的点对距离是多少。(欧几里德距离的平方)

算法讨论:

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

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

果断要去掉。否则就是TLE和AC的区别。

要区分好查询欧几里德距离和曼哈顿距离时两者的区别。

代码:

#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;
inline int read() {
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() {
n = read(); kk = read();
for(int i = 1; i <= 2 * kk; ++ i) ans.push(0);
for(int i = 1; i <= n; ++ i) {
p[i][0] = read(); p[i][1] = read();
}
root = build(1, n, 0);
for(int i = 1; i <= n; ++ i) Q(i);
output(ans.top());
return 0;
}

K-D Tree题目泛做(CXJ第二轮)的更多相关文章

  1. 基尔霍夫矩阵题目泛做(AD第二轮)

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

  2. 生成树题目泛做(AD第二轮)

    题目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 ...

  6. Link-Cut-Tree题目泛做(为了对应自己的课件)

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

  7. 【长期计划】Atcoder题目泛做

    之前学长跟我说的是700-的应该都能自己做? 然后1000-的应该都能有一定的思路? 记不清了 但总之是要智力康复一下 又加上文化课比较紧 所以这个大概就会是长期计划了 ————————————分鸽线 ...

  8. 插头DP题目泛做(为了对应WYD的课件)

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

  9. 数学期望和概率DP题目泛做(为了对应AD的课件)

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

随机推荐

  1. 在同个类中non-const插入const来减少重复

    class A { private: std::string a; public: A(std::string b) :a(b){} const char& operator[](int b) ...

  2. js学习笔记——数组方法

    join() 把数组中所有元素转化为字符串并连接起来,并返回该字符串, var arr=[1,2,3]; var str=arr.join("#"); //str="1# ...

  3. 项目中redis类似MVC的使用

  4. [linux]磁盘挂载

    最近磁盘空间不足了, 所以需要将更多的磁盘空间加进来. 因为目前占空间最多的就是home, 无论是下载还是本地用户的东西都是放在这里的. 将分区格式化为ext4, 然后使用blkid /dev/sda ...

  5. 常用meta标签整理

    < meta > 元素 概要 标签提供关于HTML文档的元数据.元数据不会显示在页面上,但是对于机器是可读的.它可用于浏览器(如何显示内容或重新加载页面),搜索引擎(关键词),或其他 we ...

  6. Feedly订阅Blog部落格RSS网摘 - Blog透视镜

    网络信息爆炸的时代,如何更有效率地阅读文章,订阅RSS网摘,可以快速地浏览文章标题,当对某些文章有兴趣时,才点下连结连到原网站,阅读更详细的文章,Feedly Reader阅读器除了提供在线版订阅RS ...

  7. XML解析之dom4j

    一.XML解析方式有两类:        一]DOM(文档对象模型)            1)一次性将整个XML文件读到内存,形成一颗DOM树        二]SAX(XML的简单API)[sim ...

  8. Configuring HTTP and HTTPS

    Configuring HTTP and HTTPS .NET Framework (current version)   Other Versions   WCF services and clie ...

  9. Python 在Visual studio 中做单元测试进行TDD开发

    Unit Tests Steve Dower edited this page on 14 Jul · 3 revisions Pages 38 Home Azure Remote Debugging ...

  10. Linux企业级项目实践之网络爬虫(13)——处理user-agent

    User Agent即用户代理,是Http协议中的一部分,属于头域的组成部分,User Agent也简称UA.它是一个特殊字符串头,是一种向访问网站提供你所使用的浏览器类型及版本.操作系统及版本.浏览 ...