QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#153214#6852. Escape The Mazejrjyy#AC ✓1131ms21532kbC++202.8kb2023-08-29 17:33:212023-08-29 17:33:22

Judging History

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

  • [2023-08-29 17:33:22]
  • 评测
  • 测评结果:AC
  • 用时:1131ms
  • 内存:21532kb
  • [2023-08-29 17:33:21]
  • 提交

answer

/* f.cpp */
#include <bits/stdc++.h>

using i64 = long long;
constexpr int N = 6e5 + 5;
constexpr i64 V = 1.1e10, inf = 4e18;

struct Segment {
    i64 k = 0, b = inf;
    i64 operator()(i64 x) const {
        return k * x + b;
    }
};
struct Node;
struct PN {
    int id = 0;
    operator bool() const;
    Node *operator->() const;
};

struct Node {
    PN l, r;
    Segment s;
};
Node pool[N], *ptr = pool;
PN::operator bool() const {
    return id;
}
Node *PN::operator->() const {
    return pool + id;
}
PN newNode() {
    ++ptr;
    *ptr = Node{};
    return PN{int(ptr - pool)};
}

void modify(PN &u, i64 l, i64 r, Segment x) {
    if (!u) {
        u = newNode();
        u->s = x;
        return;
    }
    i64 m = (l + r) / 2;
    if (x(m) <= u->s(m)) {
        std::swap(x, u->s);
    }
    if (r - l == 1) {
        return;
    }
    if (x(l) <= u->s(l)) {
        modify(u->l, l, m, x);
    } else if (x(r - 1) <= u->s(r - 1)) {
        modify(u->r, m, r, x);
    }
}
void merge(PN &u, PN &v, i64 l, i64 r) {
    if (!v) {
        return;
    }
    if (!u) {
        std::swap(u, v);
        return;
    }
    modify(u, l, r, v->s);
    if (r - l == 1) {
        return;
    }
    i64 m = (l + r) / 2;
    merge(u->l, v->l, l, m);
    merge(u->r, v->r, m, r);
}
i64 query(PN u, i64 l, i64 r, i64 p) {
    if (!u) {
        return inf;
    }
    i64 m = (l + r) / 2;
    if (p < m) {
        return std::min(u->s(p), query(u->l, l, m, p));
    } else {
        return std::min(u->s(p), query(u->r, m, r, p));
    }
}

void solve() {
    int n, L;
    std::cin >> n >> L;

    std::vector<std::vector<std::pair<int, int>>> adj(n);
    for (int i = 0; i < n - 1; ++i) {
        int u, v, w;
        std::cin >> u >> v >> w;
        --u, --v;
        adj[u].emplace_back(v, w), adj[v].emplace_back(u, w);
    }

    std::vector<i64> dep(n), f(n);
    std::vector<PN> root(n);
    auto dfs = [&](auto self, int u, int fa) -> void {
        root[u] = PN{};
        for (auto [v, w] : adj[u]) if (v != fa) {
            dep[v] = dep[u] + w;
            self(self, v, u);
            merge(root[u], root[v], -V, V);
        }
        if (root[u]) {
            i64 x = dep[u] + L;
            f[u] = query(root[u], -V, V, x) + x * x;
        } else {
            f[u] = 0;
        }
        modify(root[u], -V, V, Segment{-2 * dep[u], f[u] + dep[u] * dep[u]});
    };

    int q;
    std::cin >> q;

    while (q--) {
        int x;
        std::cin >> x;
        --x;

        ptr = pool;

        dep[x] = 0;
        dfs(dfs, x, -1);
        std::cout << f[x] << '\n';
    }
}

int main() {
    std::cin.tie(nullptr)->sync_with_stdio(false);

    int t;
    std::cin >> t;

    while (t--) {
        solve();
    }

    return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 1131ms
memory: 21532kb

input:

5
6 -23131
2 1 -65179
3 2 -4529
4 3 869
5 4 -43646
6 3 72319
6
1
2
3
4
5
6
100000 -89702
2 1 90843
3 2 -51373
4 3 -37208
5 4 50738
6 4 -56753
7 2 -22185
8 6 -2522
9 5 6214
10 6 51682
11 2 97227
12 11 -72521
13 3 20844
14 9 -63596
15 1 -811
16 1 -63314
17 14 33366
18 11 -13974
19 5 82109
20 10 -35290...

output:

662650564
584430625
385965316
420865225
2352464929
662650564
0
169
1
36
169
1
205
324
576
1
25
4
2401
441
400
10201
361
1600
36
5184
4
1
4611360649
177795556
0
0
1
834747664
1387786009
0
4356
6561
410
361
1849
100
6889
16
1296
81

result:

ok 46 lines