제출 #470548

#제출 시각아이디문제언어결과실행 시간메모리
470548Namnamseo별자리 3 (JOI20_constellation3)C++17
100 / 100
594 ms47944 KiB
#include <algorithm> #include <cassert> #include <iostream> #include <map> #include <vector> using namespace std; using ll=long long; using pp=pair<int,int>; const int maxn = int(2e5) + 10; int n; int a[maxn]; pair<pp,int> gnum[maxn]; namespace { const int M = 262144; pp t[M<<1]; void build() { for (int i=1; i<=n; ++i) t[M+i] = {a[i], i}; for (int i=M-1; 1<=i; --i) t[i] = max(t[i*2], t[i*2+1]); } int maxi(int l, int r) { pp mx{}; for (l+=M, r+=M; l<=r; l/=2, r/=2) { if (l%2 == 1) mx = max(mx, t[l++]); if (r%2 == 0) mx = max(mx, t[r--]); } return mx.second; } int wrap_v(int x, int y) { int l = x, r = x; static int vs[40], vn; auto Enum = [&](int l, int r) { static int vl[20], vr[20]; int vln = 0, vrn = 0; for (l+=M, r+=M; l<=r; l/=2, r/=2) { if (l%2 == 1) vl[vln++] = l++; if (r%2 == 0) vr[vrn++] = r--; } vn = 0; copy(vl, vl+vln, vs); vn += vln; for (int i=vrn-1; 0<=i; --i) vs[vn++] = vr[i]; }; Enum(1, l-1); int lok = vn; while (lok && t[vs[lok-1]].first < y) --lok; if (lok-1 >= 0) { for (l = vs[lok-1]; l<M;) { if (t[l*2+1].first < y) l *= 2; else l = l*2+1; } l = l+1 - M; } else l = 1; Enum(r+1, n); lok = -1; while (lok+1<vn && t[vs[lok+1]].first < y) ++lok; if (lok+1 < vn) { for (r = vs[lok+1]; r<M;) { if (t[r*2].first < y) r = r*2+1; else r *= 2; } r = r-1 - M; } else r = n; return lower_bound(gnum, gnum+n, pair<pp, int>{{l, r}, -1})->second; } } vector<int> te[maxn]; int root; vector<pp> paths[maxn]; int gdfs(int l, int r) { static int gn; int me = ++gn; gnum[gn-1] = {{l, r}, me}; if (l == r) return me; int i = maxi(l, r); if (l < i) te[me].push_back(gdfs(l, i-1)); if (i < r) te[me].push_back(gdfs(i+1, r)); return me; } int tin[maxn], tout[maxn], nt; void tdfs1(int x) { tin[x] = ++nt; for (int y : te[x]) tdfs1(y); tout[x] = nt; } ll dp[maxn]; struct It { const static int M = 262144; ll t[M<<1]; void upd(int l, int r, ll v) { for (l+=M, r+=M; l<=r; l/=2, r/=2) { if (l%2==1) t[l++] += v; if (r%2==0) t[r--] += v; } } ll get(int p) { ll ret = 0; for (p+=M; p; p/=2) ret += t[p]; return ret; } } giveup; void tdfs2(int x) { ll cds = 0; for (int y:te[x]) tdfs2(y), cds += dp[y]; ll mdf = 0; for (auto &tmp:paths[x]) { int to, c; tie(to, c) = tmp; mdf = max(mdf, c + giveup.get(tin[to])); } dp[x] = cds + mdf; giveup.upd(tin[x], tout[x], -mdf); } int main() { cin.tie(0)->sync_with_stdio(0); cin >> n; for (int i=1; i<=n; ++i) cin >> a[i]; build(); ll csum = 0; root = gdfs(1, n); sort(gnum, gnum+n); { int m; cin >> m; for (;m--;) { int x, y, c; cin >> x >> y >> c; csum += c; int up = wrap_v(x, y), down = wrap_v(x, a[x]+1); paths[up].push_back({down, c}); } } tdfs1(root); tdfs2(root); ll ans = csum - dp[root]; cout << ans << '\n'; return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...