QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#263614#5421. Factories Once MoreKhNURE_KIVITL 384ms211028kbC++2010.1kb2023-11-24 23:35:372023-11-24 23:35:39

Judging History

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

  • [2023-11-24 23:35:39]
  • 评测
  • 测评结果:TL
  • 用时:384ms
  • 内存:211028kb
  • [2023-11-24 23:35:37]
  • 提交

answer

//#pragma GCC optimize("Ofast", "unroll-loops")
//#pragma GCC target("sse", "sse2", "sse3", "ssse3", "sse4")
#ifdef LOCAL
#include <iostream>
#include <cmath>
#include <algorithm>
#include <stdio.h>
#include <cstdint>
#include <cstring>
#include <string>
#include <cstdlib>
#include <vector>
#include <bitset>
#include <map>
#include <queue>
#include <ctime>
#include <stack>
#include <set>
#include <list>
#include <random>
#include <deque>
#include <functional>
#include <iomanip>
#include <sstream>
#include <fstream>
#include <complex>
#include <numeric>
#include <cassert>
#include <array>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <thread>
#else
#include <bits/stdc++.h>
#endif

#define all(a) a.begin(),a.end()
#define len(a) (int)(a.size())
#define mp make_pair
#define pb push_back
#define fir first
#define sec second
#define fi first
#define se second

using namespace std;

typedef pair<int, int> pii;
typedef long long ll;
typedef long double ld;

template<typename T>
inline bool umin(T &a, T b) {
    if (b < a) {
        a = b;
        return true;
    }
    return false;
}

template<typename T>
inline bool umax(T &a, T b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}

#ifdef LOCAL
#define D for (bool _FLAG = true; _FLAG; _FLAG = false)
#define LOG(...) print(#__VA_ARGS__" ::", __VA_ARGS__) << endl
template <class ...Ts> auto &print(Ts ...ts) { return ((cerr << ts << " "), ...); }
#else
#define D while (false)
#define LOG(...)
#endif // LOCAL

const int max_n = 1e5 + 11, inf = 1000111222;


//struct point {
//    int x, y;
//};
//
//inline bool cmp (point a, point b) {
//    return a.x < b.x || a.x == b.x && a.y < b.y;
//}
//
//inline bool cw (point a, point b, point c) {
//    return a.x * (b.y - c.y) + b.x * (c.y - a.y) + c.x * (a.y - b.y) < 0;
//}
//
//inline bool ccw (point a, point b, point c) {
//    return a.x * (b.y - c.y) + b.x * (c.y - a.y) + c.x * (a.y - b.y) > 0;
//}
//
//void convex_hull (vector<point> & a) {
//    if (len(a) <= 1) {
//        return;
//    }
//    sort (a.begin(), a.end(), cmp);
//    point p1 = a[0],  p2 = a.back();
//    vector<point> up = {p1}, down = {p1};
//    for (int i = 1; i < len(a); i++) {
//        if (i == len(a) - 1 || cw (p1, a[i], p2)) {
//            while (len(up) >= 2 && !cw(up[len(up) - 2], up.back(), a[i])) {
//                up.pop_back();
//            }
//            up.pb(a[i]);
//        }
//        if (i == len(a) - 1 || ccw (p1, a[i], p2)) {
//            while (len(down) >= 2 && !ccw(down[len(down) - 2], down.back(), a[i])) {
//                down.pop_back();
//            }
//            down.pb(a[i]);
//        }
//    }
//    a = up;
////    for (int i = len(down) - 2; i > 0; i--) {
////        a.pb(down[i]);
////    }
//}
//
//
//
//int dp[max_n][max_n], n, k, cnt[max_n];
//
//ll area(const vector<point>& fig) {
//    ll res = 0;
//    for (unsigned i = 0; i < fig.size(); i++) {
//        point p = i ? fig[i - 1] : fig.back();
//        point q = fig[i];
//        res += (p.x - q.x) * (p.y + q.y);
//    }
//    return abs(res);
//}


//inline void dfs (int v, int p = -1) {
//    cnt[v] = 1;
//    for (auto [to, len] : edge[v]) {
//        if (to == p) {
//            continue;
//        }
//        dfs(to, v);
//        for (int i1 = k; i1 >= 0; i1--) {
//            for (int j = min(cnt[to], k - i1); j >= 0; j--) {
//                umax(dp[v][i1 + j], dp[to][j] + dp[v][i1] + len * j * (k - j));
//                if (i1 + j + 1 <= k) {
//                    umax(dp[v][i1 + j + 1], dp[to][j] + dp[v][i1] + len * j * (k - j));
//                }
//            }
//        }
//        cnt[v] += cnt[to];
//    }
//    vector <point> have;
////    LOG(cnt[v]);
//    for (int i = 0; i <= min(k, cnt[v]); i++) {
//        have.pb(point{i, dp[v][i]});
////        LOG(i, dp[v][i]);
//    }
//    auto h = have;
//    convex_hull(h);
////    LOG(len(have), len(h), area(have), area(h));
////    assert(area(have) == area(h));
//    if (area(have) != area(h)) {
//        exit(3);
//    }
//}

struct dsu {
public:
    int n;
    vector <int> p, cnt;

    inline void make_set (int v) {
        p[v] = v;
    }

    dsu (int n) : n(n) {
        p.resize(n);
        cnt.assign(n, 1);
        for (int i = 0; i < n; i++) {
            make_set(i);
        }
    }

    inline int get (int v) {
        if (p[v] == v) return v;
        return p[v] = get(p[v]); /// compressing path
    }

    inline bool unite (int a, int b) {
        a = get(a);
        b = get(b);
        if (a == b) return false;
        if (cnt[a] > cnt[b]) {
            swap(a, b);
        }
        p[a] = b;
        cnt[b] += cnt[a];
        return true;
    }
};

const int debug = 0;
vector <pii> edge[max_n];

mt19937 rng(228);
template<typename T = int>
inline T randll(T l = INT_MIN, T r = INT_MAX) {
    return uniform_int_distribution<T>(l, r)(rng);
}

inline ld randld(ld l = INT_MIN, ld r = INT_MAX) {
    return uniform_real_distribution<ld>(l, r)(rng);
}


vector <int> used;
inline int dfs (int v, int &center, int sz, int p = -1) {
    int cnt = 1;
    for (auto &i : edge[v]) {
        if (i.first != p && !used[i.first]) {
            cnt += dfs(i.first, center, sz, v);
        }
    }
    if (center == -1 && cnt + cnt > sz)
        center = v;
    return cnt;
}



struct point {
    ll x, y;
    point operator + (const point & p) const {
        return point{x + p.x, y + p.y};
    }
    point operator - (const point & p) const {
        return point{x - p.x, y - p.y};
    }
    ll cross(const point & p) const {
        return x * p.y - y * p.x;
    }
};

void reorder_polygon(vector<point> & P){
    size_t pos = 0;
    for(size_t i = 1; i < P.size(); i++){
        if(P[i].y < P[pos].y || (P[i].y == P[pos].y && P[i].x < P[pos].x))
            pos = i;
    }
    rotate(P.begin(), P.begin() + pos, P.end());
}

vector<point> minkowski(vector<point> P, vector<point> Q){
    // the first vertex must be the lowest
    reorder_polygon(P);
    reorder_polygon(Q);
    // we must ensure cyclic indexing
    P.push_back(P[0]);
    P.push_back(P[1]);
    Q.push_back(Q[0]);
    Q.push_back(Q[1]);
    // main part
    vector<point> result;
    size_t i = 0, j = 0;
    while(i < P.size() - 2 || j < Q.size() - 2){
//        LOG(i, j);
        result.push_back(P[i] + Q[j]);
        auto cross = (P[i + 1] - P[i]).cross(Q[j + 1] - Q[j]);
        if(cross >= 0 && i < P.size() - 2)
            ++i;
        if(cross <= 0 && j < Q.size() - 2)
            ++j;
    }
    return result;
}


vector <ll> dp[max_n];
int n, k;

vector <int> GG;


inline void convolve (int a, int b) {
    vector <point> A(len(dp[a])), B(len(dp[b]));
    for (int i = 0; i < len(dp[a]); i++) {
        A[i] = point{ dp[a][i], i};
    }
    for (int i = 0; i < len(dp[b]); i++) {
        B[i] = point{dp[b][i], i};
    }
    auto res = minkowski(A, B);
    dp[a].resize(min(k + 1, len(A) + len(B) - 1));
    int j = 1;
    ll last = 0, val = 0;
    if (res[0].y != 0 || res[0].x != 0) {
        exit(47);
    }
//    LOG("here");
//    for (auto &i : res) {
//        LOG(i.x, i.y);
//    }
    for (int i = 1; i < len(res); i++) {
//        LOG(i);
//        LOG(res[i].y);
        while (j < res[i].y && j < len(dp[a])) {
            dp[a][j] = (j - last) * (res[i].x - val) + val * (res[i].y - last);
            if (dp[a][j] % (res[i].y - last) != 0) {
                exit(48);
            }
            dp[a][j] /= (res[i].y - last);
//            LOG(j, dp[a][j]);
            ++j;
        }
        if (j < len(dp[a])) {
            if (j != res[i].y) {
                exit(49);
            }
            dp[a][j] = res[i].x;
            ++j;
        }
        if (last > res[i].y) {
            break;
        }
        last = res[i].y;
        val = res[i].x;
    }
    LOG(len(res));
    dp[b].clear();
//    LOG(j, len(dp[a]));
    if (j != len(dp[a])) {
        exit(50);
    }
//    for (auto &kk : dp[a]) {
//        LOG(kk);
//    }
}

inline int calc (int l, int r) {
    if (l == r) {
        return GG[r];
    }
    int x = (l + r) >> 1;
    int L = calc(l, x);
    int R = calc(x + 1, r);
    convolve(R, L);
    return R;
}

int cnt[max_n];

inline void dfs (int v, int p = -1) {
    cnt[v] = 1;
    vector <int> gg;
    for (auto [to, len] : edge[v]) {
        if (to == p) {
            continue;
        }
        dfs(to, v);
        for (int j = 0; j < len(dp[to]); j++) {
            dp[to][j] += len * 1ll * j * (k - j);
        }
        gg.pb(to);
        cnt[v] += cnt[to];
    }
    if (gg.empty()) {
        dp[v].resize(2);
    }
    else {
        GG = gg;
        int where = calc(0, len(GG) - 1);
        dp[where].swap(dp[v]);
        int need = min({cnt[v], k});
        dp[v].resize(need + 1);
        for (int j = len(dp[v]) - 1; j > 0; j--) {
            umax(dp[v][j], dp[v][j - 1]);
        }
    }
}


int main() {
//    freopen("input.txt", "r", stdin);
//    freopen("output.txt", "w", stdout);

    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    m1:
    n = 1e5;
    for (int i = 0; i <= n; i++) {
        edge[i].clear();
//        for (int j = 0; j <= n; j++) {
//            dp[i][j] = 0;
//        }
    }
    k = n;
    if (!debug) {
        cin >> n >> k;
    }
    used.resize(n);
    dsu t(n);
    LOG("here");
    for (int i = 1, u, v, w; i < n; i++) {
        if (!debug) {
            cin >> u >> v >> w;
            --u, --v;
        }
        else {
            u = i, v = i - 1;
            w = randll(1, 100);
//            u = randll(0, n - 1);
//            v = randll(0, n - 1);
            while (!t.unite(u, v)) {
                u = randll(0, n - 1);
                v = randll(0, n - 1);
            }
        }
        edge[u].pb({v, w});
        edge[v].pb({u, w});
    }
    dfs(0);
    cout << dp[0][k] << '\n';
    LOG(n, k);
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 2ms
memory: 8244kb

input:

6 3
1 2 3
2 3 2
2 4 1
1 5 2
5 6 3

output:

22

result:

ok 1 number(s): "22"

Test #2:

score: 0
Accepted
time: 2ms
memory: 8240kb

input:

4 3
1 2 2
1 3 3
1 4 4

output:

18

result:

ok 1 number(s): "18"

Test #3:

score: 0
Accepted
time: 2ms
memory: 8328kb

input:

2 2
1 2 1

output:

1

result:

ok 1 number(s): "1"

Test #4:

score: 0
Accepted
time: 47ms
memory: 18304kb

input:

100000 17
37253 35652 9892
56367 53643 1120
47896 49255 4547
93065 88999 1745
5251 6742 5031
49828 50972 8974
31548 46729 1032
56341 56287 4812
21896 22838 1682
82124 90557 7307
76289 76949 7028
33834 45380 6856
15499 15064 2265
10127 5251 9920
87208 93945 9487
68990 72637 6891
91640 85004 2259
4748...

output:

4915539756

result:

ok 1 number(s): "4915539756"

Test #5:

score: 0
Accepted
time: 62ms
memory: 21952kb

input:

100000 54
52645 54121 2692
53845 52739 658
88841 87795 9298
79147 80362 6720
80683 80909 7138
30882 28439 3197
85375 85227 6903
80229 77345 445
79601 78148 7956
15262 16666 8402
87894 95824 844
17024 12005 5687
63972 65707 8592
40510 45074 9135
50774 49596 7692
37825 38581 9735
18425 8926 1747
84473...

output:

42231195087

result:

ok 1 number(s): "42231195087"

Test #6:

score: 0
Accepted
time: 74ms
memory: 24392kb

input:

100000 102
16851 15608 9173
34201 33232 4258
54234 53975 3926
85209 83376 6251
7847 6527 2379
92238 90747 5818
74729 75538 1672
98398 98838 6273
53445 54006 4317
32889 33232 9974
12450 15916 1801
40600 40892 1397
81713 79934 4580
28979 30696 8260
90747 94477 5725
54584 53210 3583
53396 53535 1868
88...

output:

175914470238

result:

ok 1 number(s): "175914470238"

Test #7:

score: 0
Accepted
time: 81ms
memory: 29280kb

input:

100000 497
25231 28005 505
36245 34348 7087
59602 57941 1691
77459 74493 7828
11601 4890 9847
11168 11760 3807
97468 93452 8094
14843 13669 488
97738 96869 5615
27369 25231 3081
79596 78931 4604
47155 45416 1728
49273 49193 7851
38358 38735 4842
18025 23117 6165
32677 32970 9931
34174 35023 9709
688...

output:

4545765711714

result:

ok 1 number(s): "4545765711714"

Test #8:

score: 0
Accepted
time: 121ms
memory: 52860kb

input:

100000 1008
9180 10823 9475
54255 56689 9732
42103 43318 4094
11647 12305 5651
63247 66770 513
88023 85592 3518
65473 66850 7176
3995 6958 9978
2408 780 982
71617 71736 9828
22243 19070 9488
41041 40935 2604
2697 6337 8631
90433 86018 7306
73087 76067 9705
92594 99998 6304
70188 68983 8730
13139 132...

output:

11601533653407

result:

ok 1 number(s): "11601533653407"

Test #9:

score: 0
Accepted
time: 384ms
memory: 209744kb

input:

100000 4998
4535 1424 2772
79531 75798 6655
29016 24101 7995
82506 82511 2829
62622 55576 6770
13299 12683 7014
10087 7482 4906
54613 61198 7397
38305 37235 7840
78676 78348 906
68742 70584 5410
96124 96972 9461
84908 86633 3419
99187 98820 1644
34611 31584 1458
18895 19637 6568
38305 39973 5203
324...

output:

464391127886092

result:

ok 1 number(s): "464391127886092"

Test #10:

score: 0
Accepted
time: 381ms
memory: 211028kb

input:

100000 9995
65827 63216 3734
63002 63137 8069
19664 18828 9617
93059 93073 5416
98904 95848 3168
32077 28643 9290
85544 83781 4681
79065 75963 8553
52322 55020 5603
19063 21141 9921
17961 14354 9378
46073 48153 7631
44812 43844 24
72171 73621 177
28060 35086 186
96739 99367 1792
39346 41459 6809
254...

output:

1257975734249836

result:

ok 1 number(s): "1257975734249836"

Test #11:

score: -100
Time Limit Exceeded

input:

100000 20006
61719 62750 1537
44716 44507 9463
9473 13052 6509
88729 91128 7872
17510 17537 3948
31118 28068 695
84397 87761 9471
46545 52049 9288
40481 42157 9669
77649 82807 4870
25263 34334 9049
87761 87116 9621
21481 22885 9068
12531 13961 118
4102 1090 7301
73658 74721 1190
93332 93176 6754
139...

output:


result: