Submission #1332318

#TimeUsernameProblemLanguageResultExecution timeMemory
1332318MisterReaper별자리 3 (JOI20_constellation3)C++20
100 / 100
620 ms221192 KiB
#include <bits/stdc++.h>

using i64 = long long;

#ifdef DEBUG
    #include "debug.h"
#else
    #define debug(...) void(23)
#endif

template<typename T>
bool chmax(T& a, T b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}

constexpr i64 inf = i64(1E18);

int N;

struct node {
    int lc = 0;
    int rc = 0;
    i64 mx = 0;
    i64 lz = 0;
    node(i64 x = 0) : mx(x) {}
    void modify(i64 x) {
        mx += x;
        lz += x;
    }
};

std::vector<node> tree(1);
int new_node() {
    tree.emplace_back();
    return int(tree.size()) - 1;
}
int new_node(i64 x) {
    tree.emplace_back(x);
    return int(tree.size()) - 1;
}

void push(int v) {
    if (tree[v].lz) {
        if (tree[v].lc) {
            tree[tree[v].lc].modify(tree[v].lz);
        }
        if (tree[v].rc) {
            tree[tree[v].rc].modify(tree[v].lz);
        }
        tree[v].lz = 0;
    }
}

void pull(int v) {
    tree[v].mx = std::max(tree[tree[v].lc].mx, tree[tree[v].rc].mx);
}

int insert(int v, int l, int r, int p, i64 x) {
    if (!v) {
        v = new_node();
    }
    if (l == r) {
        chmax(tree[v].mx, x);
        return v;
    }
    push(v);
    int mid = (l + r) >> 1;
    if (p <= mid) {
        tree[v].lc = insert(tree[v].lc, l, mid, p, x);
    } else {
        tree[v].rc = insert(tree[v].rc, mid + 1, r, p, x);
    }
    pull(v);
    return v;
}

i64 get(int v, int l, int r, int ql, int qr) {
    if (!v) {
        return 0;
    }
    if (ql == l && r == qr) {
        return tree[v].mx;
    }
    push(v);
    int mid = (l + r) >> 1;
    if (qr <= mid) {
        return get(tree[v].lc, l, mid, ql, qr);
    } else if (mid + 1 <= ql) {
        return get(tree[v].rc, mid + 1, r, ql, qr);
    } else {
        return std::max(get(tree[v].lc, l, mid, ql, mid),
                        get(tree[v].rc, mid + 1, r, mid + 1, qr));
    }
}

int modify(int v, int l, int r, int ql, int qr, i64 x) {
    if (!v) {
        v = new_node();
    }
    if (ql == l && r == qr) {
        tree[v].modify(x);
        return v;
    }
    push(v);
    int mid = (l + r) >> 1;
    if (qr <= mid) {
        tree[v].lc = modify(tree[v].lc, l, mid, ql, qr, x);
    } else if (mid + 1 <= ql) {
        tree[v].rc = modify(tree[v].rc, mid + 1, r, ql, qr, x);
    } else {
        tree[v].lc = modify(tree[v].lc, l, mid, ql, mid, x);
        tree[v].rc = modify(tree[v].rc, mid + 1, r, mid + 1, qr, x);
    }
    pull(v);
    return v;
}

int merge(int lv, int rv, int l, int r) {
    if (!lv || !rv) {
        return lv ^ rv;
    }
    if (l == r) {
        return tree[lv].mx > tree[rv].mx ? lv : rv;
    }
    push(lv);
    push(rv);
    int mid = (l + r) >> 1;
    tree[lv].lc = merge(tree[lv].lc, tree[rv].lc, l, mid);
    tree[lv].rc = merge(tree[lv].rc, tree[rv].rc, mid + 1, r);
    pull(lv);
    return lv;
}

int Merge(int lv, int rv, int x) {
    if (!lv || !rv) {
        return lv ^ rv;
    }
    modify(lv, 0, N, x + 1, N, get(rv, 0, N, 0, x));
    modify(rv, 0, N, x + 1, N, get(lv, 0, N, 0, x));
    insert(lv, 0, N, x, get(lv, 0, N, 0, x) + get(rv, 0, N, 0, x));
    lv = merge(lv, rv, 0, N);
    return lv;
}

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

    std::cin >> N;

    std::vector<int> A(N);
    for (int i = 0; i < N; ++i) {
        std::cin >> A[i];
        --A[i];
    }

    int M;
    std::cin >> M;

    i64 all_sum = 0;
    std::vector<std::array<int, 3>> B(M);
    std::vector<std::vector<int>> g(N);
    for (int i = 0; i < M; ++i) {
        std::cin >> B[i][0] >> B[i][1] >> B[i][2];
        --B[i][0], --B[i][1];
        all_sum += B[i][2];
        g[B[i][0]].emplace_back(i);
    }

    std::vector<int> lc(N, N), rc(N, N), stk;
    for (int i = 0; i < N; ++i) {
        while (!stk.empty() && A[stk.back()] <= A[i]) {
            int x = stk.back();
            rc[x] = lc[i];
            lc[i] = x;
            stk.pop_back();
        }
        stk.emplace_back(i);
    }
    while (stk.size() > 1) {
        int x = stk.back();
        stk.pop_back();
        int y = stk.back();
        rc[y] = x;
    }

    int rt = stk[0];

    std::vector<int> roots(N + 1);
    auto dfs = [&](auto&& self, int v) -> void {
        if (v == N) {
            return;
        }
        for (auto i : g[v]) {
            roots[v] = insert(roots[v], 0, N, B[i][1], B[i][2]);
        }
        self(self, lc[v]);
        self(self, rc[v]);
        roots[v] = Merge(roots[v], roots[lc[v]], A[v]);
        roots[v] = Merge(roots[v], roots[rc[v]], A[v]);
        // std::cerr << v << " :: ";
        // for (int i = 0; i <= N; ++i) {
        //     std::cerr << get(roots[v], 0, N, i, i) << " \n"[i == N];
        // }
    };
    dfs(dfs, rt);

    i64 ans = get(roots[rt], 0, N, 0, N);

    std::cout << all_sum - ans << '\n';

    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...