Submission #1344959

#TimeUsernameProblemLanguageResultExecution timeMemory
1344959ZicrusJobs (BOI24_jobs)C++20
29 / 100
2099 ms106192 KiB
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;
typedef vector<int> vi;
#define rep(i, a, b) for(int i = a; i < (b); ++i)
#define all(x) x.begin(), x.end()
#define sz(x) (int)(x).size()
constexpr ll inf = 4e18;
mt19937 mt(time(0));

struct segtree {
    ll nt;
    vector<pll> tree;
    vector<ll> lz_add;

    segtree(ll n) {
        nt = 1;
        while (nt < n) nt *= 2;
        tree = vector<pll>(2*nt, pll(-inf, -inf));
        lz_add = vector<ll>(2*nt);
        for (ll i = 0; i < n; i++) {
            tree[nt+i] = pll(-inf, i);
        }
        for (ll i = nt; i--;) {
            tree[i] = max(tree[2*i], tree[2*i+1]);
        }
    }

    void prop(ll k) {
        tree[k].first += lz_add[k];
        if (k < nt) {
            lz_add[2*k] += lz_add[k];
            lz_add[2*k+1] += lz_add[k];
        }
        lz_add[k] = 0;
    }

    pll get_max() {
        return tree[1];
    }

    void range_add(ll l, ll r, ll v) { return range_add(1, 0, nt-1, l, r, v); }
    void range_add(ll k, ll tl, ll tr, ll l, ll r, ll v) {
        prop(k);
        if (r < tl || l > tr) return;
        if (l <= tl && r >= tr) {
            lz_add[k] += v;
            prop(k);
            return;
        }
        ll mid = tl + (tr - tl) / 2;
        range_add(2*k, tl, mid, l, r, v);
        range_add(2*k+1, mid+1, tr, l, r, v);
        tree[k] = max(tree[2*k], tree[2*k+1]);
    }

    void set(ll i, ll v) { return set(1, 0, nt-1, i, v); }
    void set(ll k, ll tl, ll tr, ll i, ll v) {
        prop(k);
        if (i < tl || i > tr) return;
        if (tl == tr) {
            tree[k].first = v;
            return;
        }
        ll mid = tl + (tr - tl) / 2;
        set(2*k, tl, mid, i, v);
        set(2*k+1, mid+1, tr, i, v);
        tree[k] = max(tree[2*k], tree[2*k+1]);
    }

    ll get(ll i) { return get(1, 0, nt-1, i); }
    ll get(ll k, ll tl, ll tr, ll i) {
        prop(k);
        if (tl == tr) return tree[k].first;
        ll mid = tl + (tr - tl) / 2;
        return i <= mid ? get(2*k, tl, mid, i) : get(2*k+1, mid+1, tr, i);
    }

    void print() {
        for (ll i = 1; i < nt; i++) prop(i);
        for (ll i = nt; i < 2*nt; i++) {
            prop(i);
            if (tree[i].first > -inf/2) cerr << tree[i].first << ' ';
            else cerr << "- ";
        }
        cerr << endl;
    }
};

struct tree_dsu {
    vector<ll> p, lnk;

    tree_dsu(vector<ll> &p) : p(p), lnk(sz(p)) {
        iota(all(lnk), 0ll);
    }

    ll find(ll i) {
        if (lnk[i] != i) lnk[i] = find(lnk[i]);
        return lnk[i];
    }

    void erase(ll i) {
        if (lnk[i] == i) lnk[i] = p[i];
    }
};

void solve() {
    ll n, s; cin >> n >> s; n++;
    vector<ll> x(n), p(n+1, n);
    vector<vector<ll>> adj(n);
    for (ll i = 1; i < n; i++) {
        cin >> x[i] >> p[i];
        adj[p[i]].push_back(i);
    }
    
    vector<ll> t(n), siz(n, 1), ord;
    auto dfs = [&](auto &oink, ll i) -> void {
        t[i] = sz(ord);
        ord.push_back(i);
        for (auto &e : adj[i]) {
            oink(oink, e);
            siz[i] += siz[e];
        }
    };
    dfs(dfs, 0);
    ord.push_back(n);

    tree_dsu dsu(p);
    segtree tree(n), val(n+1);
    tree.set(0, s);
    val.set(0, s);
    val.set(n, inf);
    while (true) {
        auto [vi, i] = tree.get_max();
        i = ord[i];
        if (vi < 0) break;
        
        ll u = i, v = dsu.find(p[u]);
        ll diff = min(vi, val.get(ord[v])) - val.get(ord[u]);
        tree.range_add(t[u], t[u] + sz(adj[u]) - 1, diff);
        val.range_add(t[u], t[u] + sz(adj[u]) - 1, diff);
        while (val.get(ord[v]) <= vi) {
            dsu.erase(u);
            u = v, v = dsu.find(p[v]);
            diff = min(vi, val.get(ord[v])) - val.get(ord[u]);
            tree.range_add(t[u], t[u] + siz[u] - 1, diff);
            val.range_add(t[u], t[u] + siz[u] - 1, diff);
        }

        tree.set(t[i], -inf);
        for (auto &e : adj[i]) {
            tree.set(t[e], vi + x[e]);
            val.set(t[e], vi + x[e]);
        }
    }
    cout << val.get(0) - s << '\n';
}

int main() {
    ios::sync_with_stdio(0); cin.tie(0);
    solve();
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...