题目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;
 ;
  + ;

 inline int read() {
   ;
   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;

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

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

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 inf = 1e9;
 ;

 inline int read() {
   ;
   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;

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

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. 插头DP题目泛做(为了对应WYD的课件)

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

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

    题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. Asp.Net Core--发布到IIS

    翻译如下: 支持的操作系统 Windows 7及更高版本 Windows Server 2008 R2及更高版本 概念上,本文档中描述的IIS配置也适用于在Nano Server IIS上托管ASP. ...

  2. JavaScript中的this指向

    this是谁 技术一般水平有限,有什么错的地方,望大家指正. this代指当前对象super调用父类的构造函数,应表会运网数物,加载驱动建立链接执行SQL处理结果,直到现在每想起这三点就能想起我上大学 ...

  3. ASP.NET MVC Web API For APP

    近来很多大型的平台都公开了Web API.比如百度地图 Web API,做过地图相关的人都熟悉.公开服务这种方式可以使它易于与各种各样的设备和客户端平台集成功能,以及通过在浏览器中使用 JavaScr ...

  4. 安装centos时候自动安装vm tool,导致无法继续安装centos的解决办法

    我原先安装centos 的时候装的是CD版的,也是到这一步就卡住了,然后我在"虚拟机->取消安装vmare tool" 点击“取消安装vmare tool”,然后他就可以进行 ...

  5. JQuery笔记汇总

    jQuery相关资料 官网: jQuery官网 在线API: jQuery在线API W3School:W3School-jQuery教程(中文版哦) 下载jQuery:jQuery各版本下载 jQu ...

  6. windows下远程桌面连接centos

    最近,由于项目需要,必须要在centos下进行操作.习惯了图形界面的我,通过黑框框来远程操作服务器,着实让人难受.但是,windows自带的远程桌面工具貌似不能直接连centos.所以,只能借助其他工 ...

  7. CentOS yum的详细使用方法

    yum是什么yum = Yellow dog Updater, Modified主要功能是更方便的添加/删除/更新RPM包.它能自动解决包的倚赖性问题.它能便于管理大量系统的更新问题yum特点可以同时 ...

  8. 将Cocos2dX渲染到MFC窗口上

    引用:http://www.cnblogs.com/windeer/archive/2012/11/18/2767750.html 引言 现在智能手机已经慢慢进入大众化,移动类应用开始火爆起来,游戏类 ...

  9. 服务器保持与Mysql的连接

    服务器程序经常要访问数据库,并且服务器程序是长时间保持运行的,mysql有一个特点,当连接上数据库后不做任何操作,默认8小时候会自动关闭休 眠的连接!一般情况下很难预料什么时候程序会执行数据库操作,如 ...

  10. Atitit.并发编程原理与概论 attilax总结

    Atitit.并发编程原理与概论 attilax总结 1. 并发一般涉及如下几个方面:2 2. 线程安全性 ( 2.2 原子性 2.3 加锁机制2 2.1. 线程封闭3.3.1Ad-hoc线程封闭 3 ...