QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#71799#4474. 田野He_Ren100 ✓757ms186276kbC++238.0kb2023-01-12 01:17:572023-01-12 01:18:00

Judging History

你现在查看的是最新测评结果

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-01-12 01:18:00]
  • 评测
  • 测评结果:100
  • 用时:757ms
  • 内存:186276kb
  • [2023-01-12 01:17:57]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef __int128 LL;
typedef long double ldb;
typedef pair<int, int> pii;
const int MAXN = 500 + 5;
const ldb eps = 1e-8;

inline int sgn(ldb x) {
    return x < -eps ? -1 : x > eps ? 1 : 0;
}

struct Vector {
    ll x, y;
    Vector(void) {}
    Vector(ll _x, ll _y): x(_x), y(_y) {}
    inline ldb len(void) const {
        return sqrtl((LL)x * x + (LL)y * y);
    }
};
typedef Vector Point;

bool operator == (const Vector &p, const Vector &q) {
    return p.x == q.x && p.y == q.y;
}
bool operator != (const Vector &p, const Vector &q) {
    return !(p == q);
}
bool operator < (const Vector &p, const Vector &q) {
    return p.x != q.x ? p.x < q.x : p.y < q.y;
}
bool operator > (const Vector &p, const Vector &q) {
    return q < p;
}
Vector operator + (const Vector &p, const Vector &q) {
    return Vector(p.x + q.x, p.y + q.y);
}
Vector operator - (const Vector &p, const Vector &q) {
    return Vector(p.x - q.x, p.y - q.y);
}
ldb dist(const Vector &p, const Vector &q) {
    return (p - q).len();
}
LL cross(const Vector &p, const Vector &q) {
    return (LL)p.x * q.y - (LL)p.y * q.x;
}

bool inter(Vector a, Vector b, Vector c, Vector d) {
    LL x = cross(a - c, d - c), y = cross(b - c, d - c);

    if (x == 0 || y == 0 || (x < 0) == (y < 0))
        return 0;

    x = cross(c - a, b - a), y = cross(d - a, b - a);

    if (x == 0 || y == 0 || (x < 0) == (y < 0))
        return 0;

    return 1;
}

struct Hull {
    vector<Vector> v;
    ldb len;
    inline void initlen(void) {
        if (v.size() <= 1) {
            len = 0;
            return;
        }

        len = dist(v[0], v.back());

        for (int i = 0; i + 1 < (int)v.size(); ++i)
            len += dist(v[i], v[i + 1]);
    }
    inline bool chkin(Vector o) const {
        if (v.size() < 1)
            return 0;

        if (v.size() == 1)
            return v[0] == o;

        if (find(v.begin(), v.end(), o) != v.end())
            return 1;

        bool res = cross(v[0] - v.back(), o - v.back()) >= 0;

        for (int i = 0; i + 1 < (int)v.size() && res; ++i)
            res &= cross(v[i + 1] - v[i], o - v[i]) >= 0;

        return res;
    }
};

Vector p[MAXN];
Hull h[MAXN];

int fa[MAXN];
inline int find(int u) {
    return fa[u] == u ? u : fa[u] = find(fa[u]);
}

int main(void) {
    int n;
    scanf("%d", &n);
    static array<Vector, 2> beg[MAXN];

    for (int i = 1; i <= n; ++i) {
        for (int j = 0; j <= 1; ++j) {
            int x, y;
            scanf("%d%d", &x, &y);
            beg[i][j] = Vector(2 * x, 2 * y);
        }

        sort(beg[i].begin(), beg[i].end());
    }

    sort(beg + 1, beg + n + 1);

    int pcnt = 2 * n;

    for (int i = 1; i <= n; ++i)
        p[2 * i - 1] = beg[i][0], p[2 * i] = beg[i][1];

    static pair<ldb, bool> cost[MAXN][MAXN];
    static ldb dis[MAXN][MAXN];
    vector<pii> alive;

    for (int i = 1; i <= pcnt; ++i)
        for (int j = 1; j <= pcnt; ++j) {
            dis[i][j] = dist(p[i], p[j]);
            cost[i][j] = {0, i != j};

            if (i != j)
                alive.emplace_back(i, j);
        }

    static bool added[MAXN][MAXN];
    auto add_edge = [&](int u, int v) {
        if (added[u][v])
            return;

        added[u][v] = added[v][u] = 1;
        int nsiz = 0, i, j;

        for (auto t : alive) {
            tie(i, j) = t;

            if (inter(p[u], p[v], p[i], p[j]))
                cost[i][j] = {0, 0};
            else
                alive[nsiz++] = {i, j};
        }

        alive.resize(nsiz);
    };

    ldb ans = 0;

    for (int i = 1; i <= pcnt; i += 2) {
        fa[i] = fa[i + 1] = i;
        h[i].v = {p[i], p[i + 1]};
        h[i].len = dist(p[i], p[i + 1]) * 2;
        ans += h[i].len;
    }

    static vector< tuple<int, int, ldb>> tocost[MAXN];
    auto delcost = [&](int rt) {
        for (auto t : tocost[rt]) {
            int i, j;
            ldb k;
            tie(i, j, k) = t;

            if (cost[i][j].second)
                cost[i][j].first -= k;
        }

        tocost[rt].clear();
    };

    for (int rt = pcnt - 1; rt >= 1; rt -= 2) {
        Vector key = p[rt] + p[rt + 1];
        key.x /= 2;
        key.y /= 2;

        auto rebuild = [&](void) {
            const auto &vec = h[rt].v;

            static int in[MAXN], on[MAXN], id[MAXN];
            memset(id, 0, sizeof(id));
            memset(on, -1, (pcnt + 1) << 2);

            for (int i = 1; i <= pcnt; ++i) {
                in[i] = find(i) == find(rt) || h[rt].chkin(p[i]);

                if (!in[i])
                    continue;

                for (int j = 0; j < (int)vec.size(); ++j)
                    if (p[i] == vec[j]) {
                        on[i] = j;
                        id[j] = i;
                        in[i] = 0;
                        break;
                    }
            }

            id[(int)vec.size()] = id[0];

            for (int i = 0; i < (int)vec.size(); ++i)
                add_edge(id[i], id[i + 1]);

            int nsiz = 0, i, j;

            for (auto t : alive) {
                tie(i, j) = t;

                if (in[i] || in[j]) {
                    cost[i][j] = {0, 0};
                    continue;
                } else if (on[i] != -1 && on[j] != -1 && (on[i] + 1) % (int)vec.size() != on[j]) {
                    cost[i][j] = {0, 0};
                    continue;
                }

                alive[nsiz++] = {i, j};

                auto u = p[i], v = p[j];
                int type_u = u.x != key.x ? u.x > key.x : u.y < key.y;
                int type_v = v.x != key.x ? v.x > key.x : v.y < key.y;

                if (type_u == type_v)
                    continue;

                if (type_u && cross(u - key, v - key) >= 0) {
                    ldb k = -h[rt].len;
                    tocost[rt].emplace_back(i, j, k);
                    cost[i][j].first += k;
                }

                if (type_v && cross(v - key, u - key) > 0) {
                    ldb k = h[rt].len;
                    tocost[rt].emplace_back(i, j, k);
                    cost[i][j].first += k;
                }
            }

            alive.resize(nsiz);
        };
        rebuild();

        static int id[MAXN];
        int tot = 0;

        for (int i = rt + 1; i <= pcnt; ++i)
            id[++tot] = i;

        sort(id + 1, id + tot + 1, [&](int i, int j) {
            return cross(p[i] - p[rt], p[j] - p[rt]) > 0;
        });

        while (1) {
            static pair<ldb, int> dp[MAXN];
            auto upd = [&](int i, int j) {
                if (!cost[i][j].second)
                    return;

                ldb nxt = dp[i].first + cost[i][j].first + dis[i][j];

                if (nxt < dp[j].first)
                    dp[j] = {nxt, i};
            };

            for (int i = rt; i <= pcnt; ++i)
                dp[i] = {1e18, -1};

            dp[rt] = {0, 0};

            for (int i = rt + 1; i <= pcnt; ++i)
                upd(rt, i);

            for (int it = 1; it <= tot; ++it) {
                int i = id[it];
                upd(i, rt);

                for (int jt = it + 1; jt <= tot; ++jt)
                    upd(i, id[jt]);
            }

            if (sgn(dp[rt].first) >= 0)
                break;

            ans += dp[rt].first;

            h[rt].v.clear();

            for (int u = dp[rt].second; u != rt; u = dp[u].second)
                h[rt].v.push_back(p[u]);

            h[rt].v.push_back(p[rt]);

            delcost(rt);
            reverse(h[rt].v.begin(), h[rt].v.end());
            h[rt].initlen();

            for (int i = rt + 1; i <= pcnt; ++i)
                if (find(i) == i && h[rt].chkin(p[i])) {
                    delcost(i);
                    fa[i] = rt;
                }

            rebuild();
        }
    }

    printf("%.20lf", (double)ans / 2);
    return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 5
Accepted
time: 3ms
memory: 5772kb

input:

1
-1000000000 1000000000 1000000000 -1000000000

output:

5656854249.49238014221191406250

result:

ok found '5656854249.4923801', expected '5656854249.4923801', error '0.0000000'

Test #2:

score: 5
Accepted
time: 3ms
memory: 5908kb

input:

2
-1000000000 0 999999999 0
1000000000 -1000000000 1000000000 1000000000

output:

6472135954.99957942962646484375

result:

ok found '6472135954.9995794', expected '6472135954.9995794', error '0.0000000'

Test #3:

score: 5
Accepted
time: 0ms
memory: 6004kb

input:

10
-867607193 -135305141 -999975171 -385697275
-207651264 -335450820 -18330141 155632154
144287982 -829501401 22484074 -866061913
18915124 -494052070 651651130 -848383053
-633121247 -339495409 -300607566 -719982203
252936986 77462552 574102244 243741641
-154713286 287468543 -95274042 297524911
74765...

output:

5067066405.41104316711425781250

result:

ok found '5067066405.4110432', expected '5067066405.4110432', error '0.0000000'

Test #4:

score: 5
Accepted
time: 2ms
memory: 10056kb

input:

15
-701938148 410589899 -652838309 549524200
377170320 731397800 384016279 739851156
-803225357 -275587279 -855622682 -258807623
-461690205 -492333831 -478066974 -502172799
244418298 768936733 189258546 797657836
301312803 -876384453 228146524 -877610003
853904999 -72058511 845162124 147849287
52159...

output:

2687409271.17388343811035156250

result:

ok found '2687409271.1738834', expected '2687409271.1738830', error '0.0000000'

Test #5:

score: 5
Accepted
time: 0ms
memory: 7948kb

input:

15
966028128 102749384 733159511 58111526
-183840981 -964762635 -25486217 -825885826
-453941617 685131856 -281117787 771697794
-560866145 3228988 -460246687 -157493879
-505599627 384217912 -220842902 401980214
-106976421 -161301927 -69655148 -237567980
-31954849 -347961087 376791221 -645856636
-1224...

output:

6449155267.93927860260009765625

result:

ok found '6449155267.9392786', expected '6449155267.9392805', error '0.0000000'

Test #6:

score: 5
Accepted
time: 2ms
memory: 7864kb

input:

15
-903973104 -777472938 -785792391 -870617608
576325989 -720374483 647995915 -794981301
-446193955 -599301915 -600026056 -917460300
-74534548 -764576158 49017894 -993103394
-649359180 -52819916 -863419327 -20307493
-719005679 946959735 -320308895 778640464
-127910017 542267821 -129878083 369452273
...

output:

6429373450.23450183868408203125

result:

ok found '6429373450.2345018', expected '6429373450.2345009', error '0.0000000'

Test #7:

score: 5
Accepted
time: 2ms
memory: 8732kb

input:

30
563190122 -333957865 587363636 -511951394
-341513881 556110360 -391270579 448867589
-580988311 202835556 -641462468 201801587
-641909308 -89360069 -424820406 -31441513
-668445424 -524183791 -703462742 -551506048
-486708894 495524165 -433848012 505247970
563360717 342208651 553617010 369986228
-15...

output:

5338349938.16921043395996093750

result:

ok found '5338349938.1692104', expected '5338349938.1692104', error '0.0000000'

Test #8:

score: 5
Accepted
time: 5ms
memory: 6572kb

input:

30
-617035814 -243852910 -643016843 -386302613
-521949648 451322869 -534737523 441069888
244964812 565768549 249878711 654422570
-570701784 -224146049 -624506481 -147058003
662685492 -445381559 661837455 -438026356
821872936 -268292925 823114477 -269278533
448432996 367014868 387700714 474445193
-24...

output:

2708337662.46174240112304687500

result:

ok found '2708337662.4617424', expected '2708337662.4617419', error '0.0000000'

Test #9:

score: 5
Accepted
time: 4ms
memory: 6412kb

input:

30
-700372633 349585810 -734239027 364390186
616660629 360045833 600828509 354913534
-405308070 -730574006 -362956442 -733507828
-27864070 -203748513 -15799887 -202160289
-849914317 501674730 -846373112 489653852
-113670774 -567834985 34910184 -317365401
448428803 -683743895 279317770 -900269109
132...

output:

3788368896.44532251358032226562

result:

ok found '3788368896.4453225', expected '3788368896.4453225', error '0.0000000'

Test #10:

score: 5
Accepted
time: 18ms
memory: 11996kb

input:

60
-706196624 688293210 -749262369 607283470
-755795349 -177771981 -812791761 -148115792
-440949389 896060692 -440949206 896060884
-720774944 -241167647 -717609845 -140282595
-655915150 -270108563 -678368432 -188235621
-250942529 -867189662 -367458339 -830038651
465902816 -483827880 550273484 -53203...

output:

5218150472.43364620208740234375

result:

ok found '5218150472.4336462', expected '5218150472.4336452', error '0.0000000'

Test #11:

score: 5
Accepted
time: 15ms
memory: 12992kb

input:

60
270223333 -827732432 320140702 -806241065
758242372 8011654 856329836 122814302
370823194 705991854 365108216 671028192
146957178 -10966770 164365056 -10752231
55683878 98405833 89829204 74479383
-692737125 -23863403 -690572070 -25650187
477873398 784766154 478331142 787715237
-481182423 82904871...

output:

4253403570.09833669662475585938

result:

ok found '4253403570.0983367', expected '4253403570.0983386', error '0.0000000'

Test #12:

score: 5
Accepted
time: 104ms
memory: 42552kb

input:

120
-886544424 -292694094 -859558450 -312851032
-667163208 619209056 -721718464 562287913
638324357 289932734 629193460 290213764
-797563076 -522380262 -857423342 -407136562
202487837 838686830 199965679 840536787
20023166 -785965550 -42471130 -798633956
864684737 310169662 869607678 305850161
-7183...

output:

3835635809.24263954162597656250

result:

ok found '3835635809.2426395', expected '3835635809.2426391', error '0.0000000'

Test #13:

score: 5
Accepted
time: 104ms
memory: 45424kb

input:

120
298023213 -814110036 297912159 -815531428
-336175395 -690381883 -373187432 -712274349
-86033840 -96471910 -88840401 -108524048
-336342055 -606092440 -380794865 -711945405
-293512959 605526234 -293294727 605749984
-561313179 -725676639 -547702272 -744795632
228018677 -847198786 223547062 -8371406...

output:

2319940053.52548170089721679688

result:

ok found '2319940053.5254817', expected '2319940053.5254827', error '0.0000000'

Test #14:

score: 5
Accepted
time: 374ms
memory: 115944kb

input:

200
34716561 39764672 22061080 55228896
-660377419 -517382474 -648719318 -509390525
248043028 -719480151 234568231 -729862796
914074638 -296468015 912617659 -292531065
-179503730 686875937 -214692756 677581205
901127673 -325076730 922054086 -316472783
628379206 -276086051 624933640 -277844717
-63305...

output:

5041940597.28897094726562500000

result:

ok found '5041940597.2889709', expected '5041940597.2889709', error '0.0000000'

Test #15:

score: 5
Accepted
time: 338ms
memory: 89512kb

input:

200
-648655118 485242756 -640268166 464216367
142113755 882514020 148510069 898417414
886536945 106308233 886588559 106298241
-26687092 -102032857 94318632 -132787104
627156481 289595280 629898734 290494180
-738670937 536716657 -734997982 516780084
-862427536 -350218810 -869151256 -369146481
4857223...

output:

5043785576.00191688537597656250

result:

ok found '5043785576.0019169', expected '5043785576.0019131', error '0.0000000'

Test #16:

score: 5
Accepted
time: 541ms
memory: 38684kb

input:

250
360058890 -509916580 362840740 -502798222
-153142076 -451225083 -154286295 -450458735
-145089509 -442879163 -146211934 -442815652
-149081151 -456375357 -149424687 -455261021
-144859476 -447637905 -144758560 -447049609
-139617574 -444471402 -139107427 -443020558
-140494028 -451516073 -140751822 -...

output:

919773883.35814929008483886719

result:

ok found '919773883.3581493', expected '919773883.3581572', error '0.0000000'

Test #17:

score: 5
Accepted
time: 589ms
memory: 46652kb

input:

250
-528811065 241636096 -613636288 251910156
-221306314 204956125 -213370730 243437534
291383450 -825802427 277855278 -795626156
-592876414 291637628 -608495289 285811926
-571847982 639685863 -594148296 635046244
-185532932 504345094 -205400609 548035836
369411279 -564038501 356501820 -573487119
32...

output:

4717320788.99501037597656250000

result:

ok found '4717320788.9950104', expected '4717320788.9950237', error '0.0000000'

Test #18:

score: 5
Accepted
time: 641ms
memory: 177536kb

input:

250
882404864 -404709152 882495270 -404026377
-499308889 -554511665 -503672206 -564315794
-819283873 173792308 -756036150 196583327
516554385 484829217 516786252 484401886
628666422 -330547156 629033426 -330853360
-439540235 -662683346 -439540240 -662683346
-868794934 429824491 -828645865 423604009
...

output:

5659561594.35736370086669921875

result:

ok found '5659561594.3573637', expected '5659561594.3573656', error '0.0000000'

Test #19:

score: 5
Accepted
time: 695ms
memory: 144456kb

input:

250
-710094825 225679673 -724832644 232603378
43683733 789976012 46051822 787436859
734469077 -215816300 725704486 -251773653
-50310640 -949401697 -45367850 -941983430
-551675487 -407664660 -551650763 -407427033
-893771887 440177415 -879090651 444788065
-62920700 746316028 -49818147 772004425
853046...

output:

5283056855.33342170715332031250

result:

ok found '5283056855.3334217', expected '5283056855.3334255', error '0.0000000'

Test #20:

score: 5
Accepted
time: 757ms
memory: 186276kb

input:

250
-134972136 812047845 -150911216 804857235
767175823 -529342142 764965127 -547065448
160390601 -811935875 142271734 -811944545
701373268 471579750 701381436 463206949
683235534 346527072 683235534 346527077
-107488394 -802677629 -107604898 -776637892
-664644616 -593984627 -665046273 -586540240
11...

output:

5388845610.56690406799316406250

result:

ok found '5388845610.5669041', expected '5388845610.5669041', error '0.0000000'

Extra Test:

score: 0
Extra Test Passed