Submission #965373

# Submission time Handle Problem Language Result Execution time Memory
965373 2024-04-18T11:55:02 Z MisterReaper Harbingers (CEOI09_harbingers) C++17
50 / 100
1000 ms 17232 KB
#include <bits/stdc++.h>
using i64 = long long;

constexpr int maxN = 1E5 + 5;
constexpr i64 INF = 1E18;
constexpr __int128 ONE = 1;

int N;
std::vector<std::pair<int, int>> adj[maxN];
int S[maxN], V[maxN], par[maxN], D[maxN];
i64 dp[maxN];

struct line {
    i64 a, b;
    line(i64 _a, i64 _b) : a(_a), b(_b) {}
    i64 eval(i64 x) {
        return 1LL * a * x + b;
    }
    long double intersect(line rhs) {
        return (b - rhs.b) / (rhs.a - a);
    }
};
std::ostream& operator<< (std::ostream& os, line l) {
    return os << '(' << l.a << "x + " << l.b << ')';
}

struct CHTrick {
    std::deque<int> before;
    std::deque<line> dq;
    std::deque<line> rem;
    CHTrick() {}
    int size() { return (int) dq.size(); }

    i64 query(i64 x) {
        int l = 0, r = size() - 1;
        while(r - l > 3) {
            int m = (l + r) >> 1;
            if(dq[m].eval(x) >= dq[m + 1].eval(x)) {
                l = m;
            } else {
                r = m;
            }
        }

        i64 res = INF;
        for(int i = l; i <= r; i++) {
            res = std::min(res, dq[i].eval(x));
        }
        return res;
    }
    void add(line l) {
        before.emplace_back(size());
        while(size() >= 2 && ONE * (l.b - dq[0].b) * (dq[1].a - dq[0].a) <= ONE * (dq[0].a - l.a) * (dq[0].b - dq[1].b)) {
            rem.push_back(dq[0]);
            dq.pop_front();
        }
        dq.push_front(l);
    }
    void rollback() {
        dq.pop_front();
        std::deque<line> save;
        while((int) save.size() + size() != before.back()) {
            save.push_front(rem.back());
            rem.pop_front();
        }
        while(!save.empty()) {
            dq.push_front(save.back());
            save.pop_back();
        }
        before.pop_back();
    }
} CHT;
std::ostream& operator<< (std::ostream& os, CHTrick w) {
    os << '{';
    for(int i = 0; i < w.size(); i++) {
        if(i != 0) {
            os << ", ";
        }
        os << w.dq[i];
    }
    return os << '}';
}

void dfs(int v) {
    // std::cerr << "vertex: " << v << '\n';
    if(v != 1) {
        dp[v] = CHT.query(V[v]) + 1LL * D[v] * V[v] + S[v];
    }
    CHT.add({-D[v], dp[v]});
    // std::cerr << v << ' ' << CHT << '\n';
    for(auto [u, w] : adj[v]) {
        if(u == par[v]) {
            continue;
        }
        D[u] = D[v] + w;
        par[u] = v;
        dfs(u);
        // std::cerr << v << ' ' << CHT << '\n';
    }
    // std::cerr << v << " roll\n";
    CHT.rollback();
    // std::cerr << CHT << '\n';
}

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);

    std::cin >> N;
    for(int i = 1; i <= N - 1; i++) {
        int A, B, W;
        std::cin >> A >> B >> W;
        adj[A].emplace_back(B, W);
        adj[B].emplace_back(A, W);
    }

    for(int i = 2; i <= N; i++) {
        std::cin >> S[i] >> V[i];
    }

    std::fill_n(&dp[1], N, INF);
    dp[1] = 0;
    par[1] = 1;
    dfs(1);

    for(int i = 2; i <= N; i++) {
        std::cout << dp[i] << " \n"[i == N];
    }

    return 0;
}
# Verdict Execution time Memory Grader output
1 Incorrect 1 ms 4956 KB Output isn't correct
2 Correct 3 ms 5212 KB Output is correct
3 Correct 30 ms 10336 KB Output is correct
4 Correct 45 ms 12776 KB Output is correct
5 Correct 52 ms 14984 KB Output is correct
6 Correct 65 ms 17232 KB Output is correct
7 Incorrect 44 ms 10312 KB Output isn't correct
8 Execution timed out 1054 ms 11736 KB Time limit exceeded
9 Incorrect 389 ms 14932 KB Output isn't correct
10 Execution timed out 1056 ms 12816 KB Time limit exceeded