二叉搜索树: http://blog.youkuaiyun.com/npy_lp/article/details/7426431
AVL搜索树:http://wenku.baidu.com/link?url=fDbBrwiRN7_SRbcyOm07616IOckh3iYc5POssnQkgSeSscSD7_hjRSMRZpwiLamclVeu3F8xitxBbDCxecFVTbjQhhZYQczMTF6Sd-KmrHi
红黑树:http://blog.youkuaiyun.com/eric491179912/article/details/6179908
伸展树:http://www.cnblogs.com/kernel_hcy/archive/2010/03/17/1688360.html
Treap树堆:http://www.cnblogs.com/shuaiwhu/archive/2012/05/06/2485894.html
SBT:http://www.cnblogs.com/zgmf_x20a/archive/2008/11/14/1333205.html
跳跃表:http://dsqiu.iteye.com/blog/1705530
左偏树:图解:http://www.cppblog.com/guogangj/archive/2009/10/30/99833.html
实现:http://blog.youkuaiyun.com/theprinceofelf/article/details/7247454
主席树:http://blog.youkuaiyun.com/sprintfwater/article/details/9162041
kd-tree:http://blog.youkuaiyun.com/yapian8/article/details/40372967
kd-tree 题目:
Description
Given n points in 2-dimensional plane. For each point p, we can draw a circle with center p and radius r (r is the
distance between point p and the kth nearest point (except p) of p). Now we need to select m points from the n
points, such that the m circles generated by the selected m points are the largest m ones. If there are two circles
which have the same radius, then select the one with smaller id. Please calculate the area of the union region
of the m circles.
Note 1: The distance we use in this problem is the Euclidean distance, that is to say, if there are two points
p(x1, y1) and q(x2, y2), then the distance of p and q is:
dis(p,q)=dis(q,p)=sqrt( (x1-x2)^2 + (y1-y2)^2 );
Note 2: If point p is input earlier than point q, then we say point p has a smaller id.
Input
The first line contains only one positive integer T (T <= 15), representing there are T cases below.
For each case, the first line contains two positive integer n, m (2 <= n <= 100000, 1 <= m <= 1000, m <= n),
representing the number of points in 2dimensional plane and the number of points we need to select.
Then n lines, each line contains three integers x, y, k (-5000 <= x, y <= 5000, 1 <= k <= 10, k < n), representing
the information of one point: (x, y) is the coordinate, and the meaning of k is given in problem description.
We guarantee that all points are distinct.
Output
Each case a line. For each case, print the area of the union of the m circles with 2 digits after decimal point.
Sample Input
1
3 3
0 0 2
1 0 2
2 0 1
Sample Output
14.30
AuthorHu Fan
</pre>代码:<p><pre name="code" class="cpp">#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <queue>
using namespace std;
const int maxn = 100010;
const int maxr = 1010;
const double eps = 1e-8;
const double EPS = 1e-5;
#define Equ(a,b) ((fabs((a)-(b)))<(eps))
#define Less(a,b) (((a)-(b))<(-(eps)))
#define LessEqu(a,b) (((a)-(b))<(eps))
#define More(a,b) (((a)-(b))>(eps))
#define MoreEqu(a,b) (((a)-(b))>(-(eps)))
int n, m;
typedef pair<double, double> PDD;
double x[maxr], y[maxr], r[maxr];
double nx[maxr], ny[maxr], nr[maxr];
double xl[maxr], xr[maxr];
int s[maxr];
struct Point {
int x[2];
int k;
int dis;
int id;
int distance(const Point& a) const {
int res = 0;
for(int i = 0; i < 2; i++) {
res += (x[i] - a.x[i]) * (x[i] - a.x[i]);
}
return res;
}
bool operator < (const Point& a) const {
return dis < a.dis;
}
}ps[maxn], qs[maxn], tempp;
bool cmp_dis(const Point& a, const Point& b) {
if(a.dis != b.dis) return a.dis > b.dis;
else return a.id < b.id;
}
int Div[maxn];
int cmpdiv;
priority_queue <Point> q;
bool cmp(const Point& a, const Point& b) {
return a.x[cmpdiv] < b.x[cmpdiv];
}
void Build_kdTree(int l, int r, Point* p, int depth) {
if(l > r) return;
int mid = (l + r) >> 1;
Div[mid] = depth % 2;
cmpdiv = Div[mid];
nth_element(p + l, p + mid, p + r + 1, cmp);
Build_kdTree(l, mid - 1, p, depth + 1);
Build_kdTree(mid + 1, r, p, depth + 1);
}
void Query(int l, int r, Point* p, Point a) {
if(l > r) return;
int mid = (l + r) >> 1;
tempp = p[mid];
tempp.dis = a.distance(tempp);
if(tempp.dis != 0) {
if(q.size() < a.k) q.push(tempp);
else if(tempp.dis < q.top().dis) {
q.pop();
q.push(tempp);
}
}
int d = a.x[Div[mid]] - tempp.x[Div[mid]];
int l1 = l, r1 = mid - 1;
int l2 = mid + 1, r2 = r;
if(d > 0) l1 ^= l2 ^= l1 ^= l2, r1 ^= r2 ^= r1 ^= r2;
Query(l1, r1, p, a);
if(q.size() < a.k || d * d < q.top().dis) {
Query(l2, r2, p, a);
}
}
inline bool cmp1(int a,int b) {
if(Equ(x[a] - r[a], x[b] - r[b])) return Less(x[a] + r[a], x[b] + r[b]);
return Less(x[a] - r[a], x[b] - r[b]);
}
inline bool cmp0(int a, int b) {
return More(r[a], r[b]);
}
int L, R;
PDD se[maxr];
inline double f(double v) {
int sz = 0, i, j;
double ret = 0.0;
for(i = L; i < R; ++i) {
if(LessEqu(v, xl[i]) || MoreEqu(v, xr[i])) continue;
j = s[i];
double d = sqrt(r[j]- (v - x[j]) * (v - x[j]));
se[sz].first = y[j] - d;
se[sz].second = y[j] + d;
++sz;
}
sort(se, se + sz);
for(i = 0; i < sz; ++i) {
double nowl, nowr;
nowl = se[i].first;
nowr = se[i].second;
for(j = i + 1; j < sz; ++j) {
if(More(se[j].first, nowr)) {
break;
}else {
if(More(se[j].second, nowr)) nowr = se[j].second;
}
}
ret += nowr - nowl;
i = j - 1;
}
return ret;
}
#define fs(x) ((x) < 0 ? (-(x)) : (x))
inline double rsimp(double l, double m, double r, double sl, double sm, double sr, double tot) {
double m1 = (l + m) * 0.5, m2 = (m + r) * 0.5;
double s0 = f(m1), s2 = f(m2);
double gl = (sl + sm + s0 + s0 + s0 + s0) * (m - l), gr = (sm + sr + s2 + s2 + s2 + s2) * (r - m);
if(fs(gl + gr - tot) < EPS) return gl + gr;
return rsimp(l, m1, m, sl, s0, sm, gl) + rsimp(m, m2, r, sm, s2, sr, gr);
}
void deal() {
int i, j = 0, k;
for(i = 0; i < m; ++i) {
s[i] = i;
}
sort(s, s + m, cmp0);
for(i = 0; i < m; ++i){
for(k = 0; k < j; ++k)
if(LessEqu((nx[k] - x[s[i]]) * (nx[k] - x[s[i]]) + (ny[k] - y[s[i]]) * (ny[k] - y[s[i]])
, (nr[k] - r[s[i]]) * (nr[k] - r[s[i]]))) break;
if(k == j) {
nx[j] = x[s[i]];
ny[j] = y[s[i]];
nr[j] = r[s[i]];
s[j] = j;
j++;
}
}
m = j;
for(i = 0; i < m; ++i) {
x[i] = nx[i], y[i] = ny[i], r[i] = nr[i];
}
}
void Round_S_Union() {
sort(s, s + m, cmp1);
double lo, hi, ans = 0.0;
int i, j;
for(i = 0; i < m; ++i) {
xl[i] = x[s[i]] - r[s[i]], xr[i] = x[s[i]] + r[s[i]], r[s[i]] *= r[s[i]];
}
for(i = 0; i < m; ++i) {
double ilo, ihi;
ilo = xl[i];
ihi = xr[i];
for(j = i + 1; j < m; ++j) {
if(More(xl[j], ihi)) break;
if(More(xr[j], ihi)) ihi = xr[j];
}
double lo = ilo;
double hi = ihi;
L = i;
R = j;
double mid = (lo + hi) * 0.5;
double sl = f(lo), sm = f(mid), sr = f(hi);
double tot = sl + sr + sm + sm + sm + sm;
ans += rsimp(lo, mid, hi, sl, sm, sr, tot);
i = j - 1;
}
printf("%.2f\n", ans / 6.0);
}
int main() {
int T, tcase = 1;
scanf("%d", &T);
while(T--) {
scanf("%d%d", &n, &m);
for(int i = 0; i < n; i++) {
scanf("%d%d%d", &ps[i].x[0], &ps[i].x[1], &ps[i].k);
ps[i].id = i;
qs[i] = ps[i];
}
Build_kdTree(0, n - 1, qs, 0);
for(int i = 0; i < n; i++) {
Query(0, n - 1, qs, ps[i]);
Point req = q.top();
ps[i].dis = ps[i].distance(req);
while(!q.empty()) {
q.pop();
}
}
sort(ps, ps + n, cmp_dis);
for(int i = 0; i < m; i++) {
x[i] = ps[i].x[0];
y[i] = ps[i].x[1];
r[i] = sqrt(1.0 * ps[i].dis);
}
deal();
Round_S_Union();
}
return 0;
}