Sicily 1912. Crop circles

来源:互联网 发布:知乎怎么查看问题 编辑:程序博客网 时间:2024/06/03 22:49

1912. Crop circles

Constraints

Time Limit: 3 secs, Memory Limit: 64 MB

Description

Is there really a monster living in Loch Ness?
Did the lost city of Atlantis ever exist?
Are UFOs tricks of the light, or actually vehicles from outer space?
Who is responsible for the strange patterns called crop circles-clever hoaxers or alien beings?
As we can see, there are so many mysterious places, creatures and events in the world which puzzled people for centuries. In this problem, we won't go through all that puzzles. Which we are interested in is this one - crop circles.

You have probably seen pictures of crop circles. (i.e. see above) They are circular patterns which mysteriously appear in fields of crop, such as wheat and barley. For research, we model these patterns as N circles in the plane and number them with 1, 2,..., N . Each of them has its center (Xi, Yi) , radius Ri and an importance value Vi which is evaluated by the scientists.

After our observation, we found that there aren't any two circles touch each other in the crop circles. But it's possible that a circle is completely within another one. When we are in a certain circle, we should pass through its borderline once in order to get out from it.

For two distinct circles A and B, if one can go to B from A without passing through more than K borderlines, we say that A and B are connected. Here comes the problem: For all connected cycle pairs (A, B), what's the maximum difference of the importance value between them? The difference of the importance value between A and B can be defined as | VA - VB| .


For example, look at the picture below. For K = 3 , the optimal solution is to select the circle 1 and 3 which make the difference of importance value 220. And there are 3 borderlines between circle 1 and 3.

| V5 - V1| = 300 , which is larger than 220, but circle 5 and circle 1 are not connected. There're 4 borderlines between them, so we won't consider these kinds of pairs.

Input

 The first line of input gives the number of cases T<=20 . T test cases follow.

The first line of each case contains two integers N , K as described above. (1 < N < 50001, 1 < K < 101) .

Next follow N lines, each contains four integers Xi , Yi , Ri , Vi , separated by spaces. The i -th line specifying the information of the i -th circle, where (Xi, Yi) are the coordinates of the center, Ri specifies the radius and Vi is the importance value. (0 < Ri ≤ 2 * 10^8, -10^9 < Xi, Yi, Vi < 10^9)

Output

 For each test case you should output a single line containing ``Case X : Y " (quotes for clarity) where X is the number of the test case (starting at 1) and Y is the maximum difference of importance value between two connected circles.

Sample Input

2 5 3 10 10 1 -200 0 0 8 10 -2 2 2 20 3 -3 3 2 3 -3 1 100 3 2 -200 0 1 0 0 0 100 2 200 0 1 10

Sample Output

Case 1: 220 

Case 2: 10

// Problem#: 1912// Submission#: 3591077// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/// All Copyright reserved by Informatic Lab of Sun Yat-sen University#include <stdio.h>#include <stdlib.h>#include <string.h>#include <math.h>#include <algorithm>#include <set>using namespace std;const int MAXN = 50005;const int INF = 0x7fffffff;const double EPS = 1e-9;int n, k;int x[MAXN], y[MAXN], r[MAXN], v[MAXN];int fa[MAXN];int cur[MAXN];int Prev[MAXN];inline long long sqr(long long x) {return x * x;}struct Event {    int id, type;    Event(int id = 0, int type = 0) {        this->id = id;        this->type = type;    }    long long x_pos() const {        return x[id] + r[id] * type;    }    bool operator < (const Event & t) const {        long long dt = (long long)x_pos() - t.x_pos();        if (dt != 0) return dt < 0;        return id < t.id;    }}e[MAXN * 2];int x_cut;struct Intersection {    int id, type;    Intersection(int id = 0, int type = 0) {        this->id = id;        this->type = type;    }    double y_pos() const {        long long s = sqr(r[id]) - sqr(x_cut - x[id]);        if (s < 0) s = 0;        return y[id] + sqrt((double)s) * type;    }    bool operator < (const Intersection & t) const {        double dt = y_pos() - t.y_pos();        if (fabs(dt) > EPS) return dt < 0;        if (id != t.id) return id < t.id;        return type < t.type;    }};set<Intersection> bst;void build() {    for (int i = 0; i < n; i++) {        e[i] = Event(i, - 1);        e[i + n] = Event(i, 1);    }    sort(e, e + n * 2);    bst.clear();    for (int i = 0; i < n * 2; i++) {        x_cut = e[i].x_pos();        int cur = e[i].id;        if (e[i].type < 0) {            bst.insert(Intersection(cur, 1));            set<Intersection>::iterator it;            it = bst.insert(Intersection(cur, -1)).first;            if (it == bst.begin()) {                fa[cur] = n;            } else {                it--;                if (it->type == -1) {                    fa[cur] = it->id;                } else {                    fa[cur] = fa[it->id];                }            }        } else {            bst.erase(Intersection(cur, 1));            bst.erase(Intersection(cur, -1));        }    }}int main() {    int cs;    scanf("%d", &cs);    for (int cid = 1; cid <= cs; cid++) {        scanf("%d%d", &n, &k);        for (int i = 0; i < n; i++) scanf("%d%d%d%d", x + i, y + i, r + i, v + i);        build();        v[n] = INF;        memcpy(cur, v, sizeof(int) * (n + 1));        for (int i = 1; i <= k; i++) {            memcpy(Prev, cur, sizeof(int) * (n + 1));            for (int a = 0; a < n; a++) {                int b = fa[a];                cur[a] = min(cur[a], Prev[b]);                cur[b] = min(cur[b], Prev[a]);            }        }        int ret = 0;        for (int a = 0; a < n; a++) ret = max(ret, v[a] - cur[a]);        printf("Case %d: %d\n", cid, ret);    }    return 0;}                                 


0 0
原创粉丝点击