acm 各种树的合集

来源:互联网 发布:auglar.js 编辑:程序博客网 时间:2024/05/17 04:18
线段树:http://blog.csdn.net/metalseed/article/details/8039326
二叉搜索树: http://blog.csdn.net/npy_lp/article/details/7426431
AVL搜索树:http://wenku.baidu.com/link?url=fDbBrwiRN7_SRbcyOm07616IOckh3iYc5POssnQkgSeSscSD7_hjRSMRZpwiLamclVeu3F8xitxBbDCxecFVTbjQhhZYQczMTF6Sd-KmrHi
红黑树:http://blog.csdn.net/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.csdn.net/theprinceofelf/article/details/7247454
主席树:http://blog.csdn.net/sprintfwater/article/details/9162041
kd-tree:http://blog.csdn.net/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;}


0 0
原创粉丝点击