Submission #420122

# Submission time Handle Problem Language Result Execution time Memory
420122 2021-06-08T06:20:40 Z JerryLiu06 Harbingers (CEOI09_harbingers) C++17
80 / 100
194 ms 35916 KB
#include <bits/stdc++.h>
 
using namespace std;
 
using ll = long long;
using ld = long double;
using db = double;
using str = string;
 
using pi = pair<int, int>;
using pl = pair<ll, ll>;
using pd = pair<db, db>;
 
using vi = vector<int>;
using vb = vector<bool>;
using vl = vector<ll>;
using vd = vector<db>;
using vs = vector<str>;
using vpi = vector<pi>;
using vpl = vector<pl>;
using vpd = vector<pd>;
 
#define mp make_pair
#define f first
#define s second
 
#define sz(x) (int)(x).size()
#define bg(x) begin(x)
#define all(x) bg(x), end(x)
#define sor(x) sort(all(x))
#define ft front()
#define bk back()
#define pb push_back
#define pf push_front
 
#define lb lower_bound
#define ub upper_bound
 
#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define F0R(i, a) FOR(i, 0, a)
#define ROF(i, a, b) for (int i = (b) - 1; i >= (a); i--)
#define R0F(i, a) ROF(i, 0, a)
#define EACH(a, x) for (auto& a : x)
 
const int MOD = 1e9 + 7;
const int MX = 1e5 + 10;
const ll INF = 1e18;

// Description: Li Chao Segment Tree. You can add lines of the form kx + m, and query maximum
// values at points x. *Useful for dynamic programming (CHT)* Time: O(lg N)

struct Line {
    ll M, C; Line() { M = 0, C = INF; } Line(ll _M, ll _C) { M = _M; C = _C; }

    ll operator()(ll X) { return M * X + C; }
};

vl allV;

struct LiChaoSegTree {
    Line tree[4 * MX]; stack<pair<int, Line>> stck;

    void update(int x, int l, int r, Line line) { int mid = (l + r) / 2;
        bool L = tree[x](allV[l]) > line(allV[l]); bool M = tree[x](allV[mid]) > line(allV[mid]); bool R = tree[x](allV[r]) > line(allV[r]);

        if (L == R) { if (L) { swap(tree[x], line); stck.push({x, line}); } return ; }

        if (L == M) { if (L) { swap(tree[x], line); stck.push({x, line}); } update(2 * x + 1, mid + 1, r, line); }
        if (M == R) { if (R) { swap(tree[x], line); stck.push({x, line}); } update(2 * x, l, mid, line); }
    }
    ll query(int x, int l, int r, int pos) {
        int mid = (l + r) / 2; if (l == r) return tree[x](allV[pos]);
        
        if (pos <= mid) return min(tree[x](allV[pos]), query(2 * x, l, mid, pos));
        if (pos > mid) return min(tree[x](allV[pos]), query(2 * x + 1, mid + 1, r, pos));
    }
    void rollback(int prevSz) {
        while (sz(stck) > prevSz) { 
            tree[stck.top().f] = stck.top().s; stck.pop(); 
        }
    } 
};

int N; vpi adj[MX]; ll S[MX], V[MX]; ll DP[MX]; LiChaoSegTree LC;

void DFS(int X, int P, ll depth) {
    if (X > 1) {
        DP[X] = LC.query(1, 0, sz(allV) - 1, lb(all(allV), V[X]) - allV.bg()) + V[X] * depth + S[X];
    }

    int cur = sz(LC.stck); LC.update(1, 0, sz(allV) - 1, Line(-depth, DP[X]));

    EACH(Y, adj[X]) if (Y.f != P) DFS(Y.f, X, depth + Y.s);
    
    LC.rollback(cur);
}

int main() {
    ios_base::sync_with_stdio(false); cin.tie(0);

    cin >> N; F0R(i, N - 1) { int A, B, L; cin >> A >> B >> L; adj[A].pb({B, L}), adj[B].pb({A, L}); }

    FOR(i, 2, N + 1) cin >> S[i] >> V[i], allV.pb(V[i]);

    sor(allV); allV.erase(unique(all(allV)), allV.end()); 

    DFS(1, 0, 0); FOR(i, 2, N + 1) cout << DP[i] << " ";
}

Compilation message

harbingers.cpp: In member function 'll LiChaoSegTree::query(int, int, int, int)':
harbingers.cpp:76:5: warning: control reaches end of non-void function [-Wreturn-type]
   76 |     }
      |     ^
# Verdict Execution time Memory Grader output
1 Correct 5 ms 8908 KB Output is correct
2 Correct 8 ms 9456 KB Output is correct
3 Correct 79 ms 21492 KB Output is correct
4 Correct 122 ms 30208 KB Output is correct
5 Correct 183 ms 27800 KB Output is correct
6 Correct 176 ms 28224 KB Output is correct
7 Correct 98 ms 19516 KB Output is correct
8 Correct 194 ms 30320 KB Output is correct
9 Runtime error 194 ms 35916 KB Memory limit exceeded
10 Runtime error 154 ms 32916 KB Memory limit exceeded