Submission #867620

#TimeUsernameProblemLanguageResultExecution timeMemory
867620NeroZeinConstellation 3 (JOI20_constellation3)C++17
100 / 100
318 ms60436 KiB
#include "bits/stdc++.h" using namespace std; #ifdef Nero #include "Deb.h" #else #define deb(...) #endif const int N = 2e5 + 5; int a[N]; int x[N], y[N], c[N]; int leaf[N]; int L[N], R[N]; long long dp[N]; int prop[N * 2]; vector<int> g[N]; long long tree[N]; vector<int> in_col[N]; int cnt, in[N], out[N]; vector<pair<int, int>> vec[N]; map<pair<int, int>, vector<pair<int, int>>> mp; int search(vector<int>& mono, int v) { int lo = 0, hi = (int) mono.size() - 1; while (lo < hi) { int mid = (lo + hi + 1) / 2; if (a[mono[mid]] >= v) lo = mid; else hi = mid - 1; } return mono[lo]; } void assign(int nd, int l, int r, int s, int e, int v) { if (l >= s && r <= e) { prop[nd] = min(prop[nd], v); return; } int mid = (l + r) >> 1; int rs = nd + ((mid - l + 1) << 1); if (mid >= e) { assign(nd + 1, l, mid, s, e, v); } else { if (mid < s) { assign(rs, mid + 1, r, s, e, v); } else { assign(nd + 1, l, mid, s, e, v); assign(rs, mid + 1, r, s, e, v); } } } int get(int nd, int l, int r, int p) { int ret = prop[nd]; if (l == r) { return ret; } int mid = (l + r) >> 1; int rs = nd + ((mid - l + 1) << 1); if (p <= mid) { return min(ret, get(nd + 1, l, mid, p)); } else { return min(ret, get(rs, mid + 1, r, p)); } } void pre(int v) { in[v] = cnt++; for (int u : g[v]) { pre(u); } //deb(v) deb(in[v]) cout << '\n'; out[v] = cnt - 1; } void upd(int i, long long v) { ++i; while (i < N) { tree[i] += v; i += i & -i; } } long long qry(int i) { ++i; long long ret = 0; while (i) { ret += tree[i]; i -= i & -i; } return ret; } void dfs(int v) { for (int u : g[v]) { dfs(u); dp[v] += dp[u]; } for (int u : g[v]) { upd(in[v], dp[u]); upd(out[v] + 1, -dp[u]); upd(in[u], -dp[u]); upd(out[u] + 1, dp[u]); } for (auto [val, col] : vec[v]) { int pos = in[leaf[col]]; dp[v] = max(dp[v], val + qry(pos)); } } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n; cin >> n; for (int i = 1; i <= n; ++i) { cin >> a[i]; } int m; cin >> m; long long ans = 0; for (int i = 1; i <= m; ++i) { cin >> x[i] >> y[i] >> c[i]; in_col[x[i]].push_back(i); ans += c[i]; } vector<int> stk; stk.push_back(0); a[0] = INT_MAX; for (int i = 1; i <= n; ++i) { while (a[stk.back()] < a[i]) { stk.pop_back(); } for (int j : in_col[i]) { L[j] = search(stk, y[j]) + 1; } stk.push_back(i); } stk.resize(1); stk[0] = n + 1; a[n + 1] = INT_MAX; for (int i = n; i >= 1; --i) { while (a[stk.back()] < a[i]) { stk.pop_back(); } for (int j : in_col[i]) { R[j] = search(stk, y[j]) - 1; } stk.push_back(i); } for (int i = 1; i <= m; ++i) { mp[make_pair(L[i], R[i])].emplace_back(c[i], x[i]); } vector<pair<int, int>> ranges; for (auto i : mp) { ranges.push_back(i.first); } sort(ranges.begin(), ranges.end(), [&](pair<int, int> i, pair<int, int> j) { return i.second - i.first < j.second - j.first; }); set<pair<int, int>> active; memset(prop, 63, sizeof prop); for (int i = 0; i < (int) ranges.size(); ++i) { while (true) { auto it = active.lower_bound(make_pair(ranges[i].first, -1)); if (it != active.end() && it -> first <= ranges[i].second) { g[i].push_back(it -> second); active.erase(it); } else { break; } } vec[i] = mp[ranges[i]]; active.emplace(ranges[i].first, i); assign(0, 1, n, ranges[i].first, ranges[i].second, i); } for (auto it : active) { g[n].push_back(it.second); } assign(0, 1, n, 1, n, n); for (int i = 1; i <= n; ++i) { leaf[i] = get(0, 1, n, i); } pre(n); dfs(n); ans -= dp[n]; cout << ans << '\n'; return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...