Submission #1343265

#TimeUsernameProblemLanguageResultExecution timeMemory
1343265WansurWorst Reporter 4 (JOI21_worst_reporter4)C++20
14 / 100
2103 ms230472 KiB
#include <bits/stdc++.h>
#define ent '\n'
#define int long long

#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#pragma GCC optimize("Ofast,unroll-loops,fast-math,O3")

using namespace std;

const int maxn = 200'200;

vector<int> g[maxn], e[maxn], adj[maxn];
int t[maxn * 4], p[maxn * 4], mx[maxn * 4], comp[maxn];
int c[maxn], cost[maxn], a[maxn], h[maxn];
int used[maxn], is[maxn];
int n, N, tN;

void init(int v, int tl, int tr) {
    if(!t[v] && !p[v] && !mx[v]) return;

    t[v] = p[v] = mx[v] = 0;

    if(tl == tr) return;

    int mid = (tl + tr) >> 1;
    init(v * 2, tl, mid);
    init(v * 2 + 1, mid + 1, tr);

}

void push(int v, int tl, int tr) {
    if(tl == tr) return;

    mx[v * 2] += p[v], mx[v * 2 + 1] += p[v];
    t[v * 2] += p[v], t[v * 2 + 1] += p[v];
    p[v * 2] += p[v], p[v * 2 + 1] += p[v];
    p[v] = 0;
}

void upd(int v, int tl, int tr, int l, int r, int x) {
    if(tl > r || l > tr || l > r) return;
    if(tl >= l && tr <= r) {
        mx[v] += x, t[v] += x, p[v] += x;
        return;
    }
    push(v, tl, tr);

    int mid = (tl + tr) >> 1;
    upd(v * 2, tl, mid, l, r, x);
    upd(v * 2 + 1, mid + 1, tr, l, r, x);

    t[v] = min(t[v * 2], t[v * 2 + 1]);
    mx[v] = max(mx[v * 2], mx[v * 2 + 1]);
}

void upd(int v, int tl, int tr, int l, int x) {
    if(tr < l || mx[v] <= x) return;
    if(tl >= l && t[v] == mx[v]) {
        int val = x - mx[v];
        mx[v] += val, t[v] += val, p[v] += val;
        return;
    }
    push(v, tl, tr);

    int mid = (tl + tr) >> 1;
    upd(v * 2, tl, mid, l, x);
    upd(v * 2 + 1, mid + 1, tr, l, x);

    t[v] = min(t[v * 2], t[v * 2 + 1]);
    mx[v] = max(mx[v * 2], mx[v * 2 + 1]);
}

int get(int v, int tl, int tr, int l, int r) {
    if(tl > r || l > tr) return 1e18;
    if(tl >= l && tr <= r) return t[v];
    push(v, tl, tr);

    int mid = (tl + tr) >> 1;
    return min(get(v * 2, tl, mid, l, r), get(v * 2 + 1, mid + 1, tr, l, r));
}

vector<int> ord;

void top_sort(int v) {
    used[v] = 1;

    for(int to : g[v]) {
        if(!used[to]) {
            top_sort(to);
        }
    }

    ord.push_back(v);
}

void calc_comp(int v, int c) {
    comp[v] = c;

    for(int to : e[v]) {
        if(!comp[to]) {
            calc_comp(to, c);
        }
    }
}

vector<int> val;
set<int> cur[maxn];
int sz[maxn], mxs[maxn];

void pre_calc(int v, int p) {
    mxs[v] = 0;
    sz[v] = 1;

    ord.push_back(v);
    for(int x : adj[v]) {
        val.push_back(h[x]);
    }

    for(int to : g[v]) {
        if(to != p) {
            pre_calc(to, v);
            sz[v] += sz[to];

            if(sz[to] > sz[mxs[v]]) {
                mxs[v] = to;
            }
        }
    }
}


void dfs(int v, int p) {
    cur[v].insert(tN + 1);

    vector<array<int, 3>> add;

    for(int to : g[v]) {
        if(to == p || to == mxs[v]) {
            continue;
        }

        dfs(to, v);

        int l = 0;
        int mn = 1e18;

        for(int x : cur[to]) {
            if(l + 1 < x) {
                int sval = get(1, 1, tN, l + 1, l + 1);
                mn = min(mn, sval);
                add.push_back({l + 1, x - 1, mn});
            }

            int dval = get(1, 1, tN, x, x);
            mn = min(mn, dval);
            add.push_back({x, x, mn});
            l = x;

            cur[v].insert(x);
        }

        init(1, 1, tN);
    }

    if(mxs[v] != 0) {
        dfs(mxs[v], v);

        cur[v].swap(cur[mxs[v]]);
        for(int x : cur[mxs[v]]) {
            cur[v].insert(x);
        }

        for(auto [l, r, x] : add) {
            upd(1, 1, tN, l, r, x);
        }
    }

    int sum = 0;
    for(int x : adj[v]) {
        sum += c[x];
        upd(1, 1, tN, 1, tN, c[x]);
        upd(1, 1, tN, h[x], get(1, 1, tN, h[x], h[x]) - c[x]);

        cur[v].insert(h[x]);
    }
}

void solve() {
    cin >> n;
    for(int i = 1; i <= n; i++) {
        cin >> a[i] >> h[i] >> c[i];

        g[i].push_back(a[i]);
        e[a[i]].push_back(i);
    }

    for(int i = 1; i <= n; i++) {
        if(!used[i]) {
            top_sort(i);
        }
    }

    reverse(ord.begin(), ord.end());
    for(int v : ord) {
        if(!comp[v]) {
            calc_comp(v, ++N);
        }
    }

    for(int i = 1; i <= n; i++) {
        g[i].clear();
        adj[comp[i]].push_back(i);

        if(comp[i] == comp[a[i]]) {
            is[comp[i]] = 1;
        }
    }

    for(int i = 1; i <= n; i++) {
        for(int to : e[i]) {
            if(comp[i] != comp[to]) {
                g[comp[i]].push_back(comp[to]);
            }
        }
    }

    int ans = 0;
    for(int v = 1; v <= N; v++) {
        if(is[v]) {
            ord.clear(), val.clear();

            pre_calc(v, 0);

            sort(val.begin(), val.end());
            val.resize(unique(val.begin(), val.end()) - val.begin());

            tN = (int)val.size();
            for(int u : ord) {
                for(int x : adj[u]) {
                    h[x] = lower_bound(val.begin(), val.end(), h[x]) - val.begin() + 1;
                    h[x] = tN - h[x] + 1;
                }
            }

            dfs(v, 0);

            ans += t[1];

            for(int i = 1; i <= tN * 4; i++) {
                t[i] = p[i] = 0;
            }
        }
    }

    cout << ans << ent;
}

int32_t main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int t = 1;
    // cin >> t;
    while(t--) {
        solve();
    }
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...