제출 #1159516

#제출 시각아이디문제언어결과실행 시간메모리
1159516FIFI_cpp별자리 3 (JOI20_constellation3)C++20
35 / 100
1594 ms33180 KiB
#include <bits/stdc++.h>
#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <cstdlib>
#include <cmath>
#include <queue>
#include <stack>
#include <deque>
#include <fstream>
#include <iterator>
#include <set>
#include <map>
#include <unordered_map>
#include <iomanip>
#include <cctype>
#include <string>
#include <cassert>
#include <set>
#include <bitset>
#include <unordered_set>
#include <numeric>

#define all(a) a.begin(), a.end()
#define fast ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define pb push_back
#define ppi pair<int,pair<int,int>>
#define int int64_t

using namespace std;
//    /\_/\
//   (= ._.)
//   / >  \>
// encouraging cat
const int INF = 10000000000000000;
//const int mod = 1000000007;
const int mod = 998244353;
const int MAXN = 200005;
//ifstream fin('xor.in');
//ofstream fout('xor.out');
vector<multiset<vector<int>>> stars;
int n;
vector<int> a, val, dp;
int res = 0;
pair<int, int> t[4*MAXN];

pair<int, int> combine(pair<int, int> a, pair<int, int> b) {
    if (a.first > b.first) 
        return a;
    return b;
}

void build(vector<int> a, int v, int tl, int tr) {
    if (tl == tr) {
        t[v] = make_pair(a[tl], tl);
    } else {
        int tm = (tl + tr) / 2;
        build(a, v*2, tl, tm);
        build(a, v*2+1, tm+1, tr);
        t[v] = combine(t[v*2], t[v*2+1]);
    }
}

pair<int, int> get_max(int v, int tl, int tr, int l, int r) {
    if (l > r)
        return make_pair(-INF, 0);
    if (l == tl && r == tr)
        return t[v];
    int tm = (tl + tr) / 2;
    return combine(get_max(v*2, tl, tm, l, min(r, tm)), 
                   get_max(v*2+1, tm+1, tr, max(l, tm+1), r));
}
pair<multiset<vector<int>>,int> solve(int l,int r, int prev_m)
{
    pair<int,int> ask = get_max(1, 0, n - 1, l + 1, r - 1);
    int m = ask.first;
    int Mpos = ask.second;
    for (int i = l + 1;i < r;i++)
    {
        if (a[i] > m)
        {
            m = a[i];
            Mpos = i;
        }
    }
    pair<multiset<vector<int>>,int> currT, rightT;
    multiset<vector<int>> curr,right;
    if (Mpos - l >= 2)
    {
        currT = solve(l, Mpos, m);
        for (auto i: currT.first)
        {
            curr.insert({i[0], i[1], i[2]});
        }
    }
    if (r - Mpos >= 2)
    {
        rightT = solve(Mpos, r, m);
        for (auto i: rightT.first)
        {
            right.insert({i[0], i[1], i[2]});
        }
    }
    if (right.size() < curr.size())
    {
        swap(curr, right);
    }
    for (auto i : stars[Mpos])
    {
        curr.insert(i);
    }
    curr.insert(all(right));
    int Lans = 0;
    int Rans = 0;
    if (Mpos - l >= 2)
    {
        Lans = dp[currT.second];
    }
    if (r - Mpos >= 2)
    {
        Rans = dp[rightT.second];
    }
    int ad = 0;
    int s = 0;
    for (auto i : curr)
    {
        if (i[0] > prev_m)
        {
            break;
        }
        s += val[i[2]];
        ad = max(ad, val[i[2]]);
    }
    int high = 0;
    for (auto i: curr)
    {
        if (i[0] <= prev_m)
        {
            continue;
        }
        high = max(high, val[i[2]]);
        val[i[2]] -= ad;
    }
    res = max(res, max(Lans + Rans + high, Lans + Rans + ad));
    dp[Mpos] = Lans + Rans + ad;
    auto it = curr.lower_bound({prev_m, INF, INF});
    curr.erase(curr.begin(), it);
    return {curr, Mpos};
}
signed main()
{
    cin >> n;
    a.resize(n);
    dp.resize(n,0);
    for (int i = 0;i < n;i++)
    {
        cin >> a[i];
    }
    build(a, 1, 0, n - 1);
    //a.push_back(INF);
    int M;
    cin >> M;
    stars.resize(n);
    val.resize(M,0);
    int s = 0;
    for (int i = 0;i < M;i++)
    {
        int x,y,c;
        cin >> x >> y >> c;
        x--;
        stars[x].insert({y,c, i});
        val[i] = c;
        s += c;
    }
    solve(-1, n, INF);
    cout << s - res << '\n';
    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...