QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#150071#5414. Stop, Yesterday Please No MorergnerdplayerRE 0ms0kbC++203.4kb2023-08-25 15:04:322023-08-25 15:04:35

Judging History

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

  • [2023-08-25 15:04:35]
  • 评测
  • 测评结果:RE
  • 用时:0ms
  • 内存:0kb
  • [2023-08-25 15:04:32]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;

using i64 = long long;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

struct Treap {
    Treap *lc = nullptr, *rc = nullptr;
    int sz = 1;
    unsigned w = rng();
    i64 m = 0, b = 0, val = 0;
};

int size(Treap *t) {
    return t == nullptr ? 0 : t->sz;
}

void pull(Treap *t) {
    t->sz = size(t->lc) + size(t->rc) + 1;
}

void apply(Treap *t, i64 m, i64 b) {
    t->m += m;
    t->b += b;
    t->val += m * size(t->lc) + b;
}

void push(Treap *t) {
    if (t->m == 0 && t->b == 0) {
        return;
    }
    if (t->lc != nullptr) {
        apply(t->lc, t->m, t->b);
    }
    if (t->rc != nullptr) {
        apply(t->rc, t->m, t->b + t->m * (size(t->lc) + 1));
    }
    t->m = t->b = 0;
}

pair<Treap*, Treap*> split(Treap *t, int s) {
    if (t == nullptr) {
        return {t, t};
    }
    push(t);
    Treap *a, *b;
    if (s <= size(t->lc)) {
        b = t;
        tie(a, b->lc) = split(t->lc, s);
    } else {
        a = t;
        tie(a->rc, b) = split(t->rc, s - size(t->lc) - 1);
    }
    pull(t);
    return {a, b};
}

Treap* merge(Treap *t1, Treap *t2) {
    if (t1 == nullptr) { return t2; }
    if (t2 == nullptr) { return t1; }
    push(t1), push(t2);
    if (t1->w < t2->w) {
        t1->rc = merge(t1->rc, t2);
        pull(t1);
        return t1;
    } else {
        t2->lc = merge(t1, t2->lc);
        pull(t2);
        return t2;
    }
}

int rnk(Treap *t, i64 val) {
    int res = 0;
    while (t != nullptr) {
        push(t);
        if (t->val >= val) {
            res += size(t->lc) + 1;
            t = t->rc;
        } else {
            t = t->lc;
        }
    }
    return res;
}

Treap* join(Treap *t1, Treap *t2) {
    if (size(t1) > size(t2)) {
        swap(t1, t2);
    }
    Treap *t = nullptr;
    while (t1 != nullptr) {
        auto [u1, v1] = split(t1, 1);
        t1 = v1;
        int r = rnk(t2, u1->val);
        if (r > 0) {
            auto [u2, v2] = split(t2, r);
            t = merge(t, u2);
            t2 = v2;
        }
        t = merge(t, u1);
    }
    t = merge(t, t2);
    return t;
}

int main() {
    cin.tie(nullptr)->sync_with_stdio(false);
    
    auto solve = [&]() {
        int n, k;
        cin >> n >> k;

        vector<vector<pair<int, int>>> adj(n);
        for (int i = 1; i < n; i++) {
            int u, v, w;
            cin >> u >> v >> w;
            u--, v--;
            adj[u].emplace_back(v, w);
            adj[v].emplace_back(u, w);
        }
        
        // dp[u][x] = max_{i + j = x} (dp[u][i] + dp[v][j] + w * j * (k - j))
        // dp[u][0] = dp[u][1] = 0
        // maintain slope ? ;

        auto dfs = [&](auto dfs, int u, int p) -> Treap* {
            Treap *tu = new Treap;
            for (auto [v, w] : adj[u]) {
                if (v == p) {
                    continue;
                }
                auto tv = dfs(dfs, v, u);
                apply(tv, -2 * w, 1LL * (k - 1) * w);
                tu = join(tu, tv);
            }
            return tu;
        };
        auto t = dfs(dfs, 0, -1);

        i64 ans = 0;

        while (k--) {
            auto [u, v] = split(t, 1);
            ans += u->val;
            t = v;
        }

        cout << ans << '\n';
    };

    solve();

    return 0;
}


Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 0
Dangerous Syscalls

input:

3
4 5 3
ULDDRR
4 5 0
UUUUUUU
4 5 10
UUUUUUU

output:


result: