제출 #582953

#제출 시각아이디문제언어결과실행 시간메모리
582953elkernos별자리 3 (JOI20_constellation3)C++17
100 / 100
403 ms66720 KiB
#include <bits/stdc++.h>

using namespace std;

const int oo = 1000 * 1000 * 1000;

struct Tree {
    typedef pair<int, int> T;
    static constexpr T unit = {-oo, -oo};
    T f(T a, T b) { return max(a, b); }
    vector<T> s;
    int n;
    Tree(int nn) : s(2 * nn), n(nn) {}
    void update(int pos, T val)
    {
        for(s[pos += n] = val; pos /= 2;) {
            s[pos] = f(s[pos * 2], s[pos * 2 + 1]);
        }
    }
    T query(int b, int e)
    {
        T ra = unit, rb = unit;
        for(b += n, e += n + 1; b < e; b /= 2, e /= 2) {
            if(b % 2) ra = f(ra, s[b++]);
            if(e % 2) rb = f(s[--e], rb);
        }
        return f(ra, rb);
    }
};

struct FT {
    typedef long long T;
    vector<T> s;
    FT(int n) : s(n) {}
    void update(int pos, T dif)
    {
        for(; pos < (int)s.size(); pos |= pos + 1) {
            s[pos] += dif;
        }
    }
    T query(int pos)
    {
        T res = 0;
        for(pos++; pos >= 1; pos &= pos - 1) {
            res += s[pos - 1];
        }
        return res;
    }
};

struct gwiazdeczka {
    int x, y, c;
    void read() { cin >> x >> y >> c; }
    bool operator<(const gwiazdeczka &he) const { return x < he.x; }
};

int main()
{
    cin.tie(nullptr)->sync_with_stdio(0);
    int n;
    cin >> n;
    vector<int> a(n + 1);
    Tree t1(n + 123);
    for(int i = 1; i <= n; i++) {
        cin >> a[i];
        t1.update(i, {a[i], i});
    }
    int m;
    cin >> m;
    vector<gwiazdeczka> stars(m + 1);
    long long sum = 0;
    for(int i = 1; i <= m; i++) {
        stars[i].read();
        sum += stars[i].c;
    }
    sort(stars.begin() + 1, stars.end());
    Tree t2(m + 123);
    for(int i = 1; i <= m; i++) {
        t2.update(i, {stars[i].y, i});
    }
    int now = 0;
    vector<vector<int>> g(n + 1), paths(n + 1);
    vector<int> ends(n + 1);
    function<void(int, int, int)> rek = [&](int l, int r, int p) {
        if(l > r) {
            return;
        }
        now++;
        if(p) {
            g[p].push_back(now);
        }
        pair<int, int> split = t1.query(l, r);
        ends[split.second] = now;
        int lo = lower_bound(stars.begin() + 1, stars.end(), gwiazdeczka{l, 0, 0}) - stars.begin();
        int hi = upper_bound(stars.begin() + 1, stars.end(), gwiazdeczka{r, 0, 0}) - stars.begin() - 1;
        while(1) {
            pair<int, int> maybe = t2.query(lo, hi);
            if(maybe.first <= split.first) {
                break;
            }
            paths[now].push_back(maybe.second);
            t2.update(maybe.second, pair<int, int>{-oo, -oo});
        }
        rek(l, split.second - 1, ends[split.second]); //! JA PIERDOLE XDDD
        rek(split.second + 1, r, ends[split.second]);
    };
    rek(1, n, 0);
    vector<long long> dp(n + 1);
    int len = 0;
    vector<int> pre(n + 1), post(n + 1);
    FT tsum(n + 123);
    function<void(int)> dfs = [&](int u) {
        pre[u] = ++len;
        for(int to : g[u]) {
            dfs(to);
            dp[u] += dp[to];
        }
        post[u] = len;
        tsum.update(pre[u], dp[u]);
        tsum.update(post[u] + 1, -dp[u]);
        for(int i : paths[u]) {
            dp[u] = max(dp[u], tsum.query(pre[ends[stars[i].x]]) + stars[i].c);
        }
        tsum.update(pre[u], -dp[u]);
        tsum.update(post[u] + 1, dp[u]);
    };
    dfs(1);
    cout << sum - dp[1] << '\n';
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...