Submission #916083

#TimeUsernameProblemLanguageResultExecution timeMemory
916083boris_mihovConstellation 3 (JOI20_constellation3)C++17
35 / 100
1554 ms93268 KiB
#include <algorithm> #include <iostream> #include <cassert> #include <numeric> #include <vector> #include <stack> typedef long long llong; const int MAXLOG = 19; const int MAXN = 400000 + 10; const int INF = 1e9; int n, m; int a[MAXN]; int h[MAXN]; int cntSegm; struct Sparse { int sparse[MAXLOG][MAXN]; void build(int par[]) { for (int i = 1 ; i <= cntSegm ; ++i) { sparse[0][i] = par[i]; } for (int log = 1 ; (1 << log) <= cntSegm ; ++log) { for (int i = 1 ; i <= cntSegm ; ++i) { sparse[log][i] = sparse[log - 1][sparse[log - 1][i]]; } } } int find(int x, int y) { for (int log = MAXLOG - 1 ; log >= 0 ; --log) { if (h[sparse[log][x]] < y) { x = sparse[log][x]; } } return x; } }; int x[MAXN]; int y[MAXN]; int c[MAXN]; int par[MAXN]; llong dp[MAXN]; llong sum[MAXN]; int leftSegm[MAXN]; int rightSegm[MAXN]; int leftBigger[MAXN]; std::vector <int> g[MAXN]; std::vector <int> stars[MAXN]; std::stack <int> st; Sparse sparse; llong getSum(int node, int to) { if (node == to) { return sum[node] - dp[node]; } return sum[node] - dp[node] + getSum(par[node], to); } void dfs(int node) { for (const int &u : g[node]) { dfs(u); sum[node] += dp[u]; } llong res = sum[node]; for (const int &idx : stars[node]) { res = std::max(res, c[idx] + getSum(par[leftSegm[x[idx]]], node)); } dp[node] = res; } void solve() { a[0] = INF; h[0] = INF; st.push(0); for (int i = 1 ; i <= n ; ++i) { while (a[st.top()] < a[i]) { st.pop(); } leftBigger[i] = st.top(); st.push(i); } while (st.size()) { st.pop(); } for (int i = 1 ; i <= n ; ++i) { bool wasThere = false; if (a[leftBigger[i]] == a[i]) { wasThere = true; leftSegm[i] = rightSegm[leftBigger[i]]; } else { leftSegm[i] = ++cntSegm; } rightSegm[i] = ++cntSegm; h[leftSegm[i]] = a[i]; h[rightSegm[i]] = a[i]; while (st.size() && a[st.top()] < a[i]) { if (!wasThere && (par[leftSegm[st.top()]] == 0 || h[par[leftSegm[st.top()]]] > a[i])) { par[rightSegm[st.top()]] = leftSegm[i]; par[leftSegm[st.top()]] = leftSegm[i]; } st.pop(); } if (st.size()) { if (a[st.top()] > a[i]) { par[leftSegm[i]] = rightSegm[st.top()]; par[rightSegm[i]] = rightSegm[st.top()]; } else { par[leftSegm[i]] = par[rightSegm[st.top()]]; par[rightSegm[i]] = par[rightSegm[st.top()]]; } } st.push(i); } for (int i = 1 ; i <= cntSegm ; ++i) { g[par[i]].push_back(i); } sparse.build(par); llong sumStars = 0; for (int i = 1 ; i <= m ; ++i) { stars[par[sparse.find(leftSegm[x[i]], y[i])]].push_back(i); sumStars += c[i]; } dfs(0); std::cout << sumStars - dp[0] << '\n'; } void input() { std::cin >> n; for (int i = 1 ; i <= n ; ++i) { std::cin >> a[i]; } std::cin >> m; for (int i = 1 ; i <= m ; ++i) { std::cin >> x[i] >> y[i] >> c[i]; } } void fastIOI() { std::ios_base :: sync_with_stdio(0); std::cout.tie(nullptr); std::cin.tie(nullptr); } int main() { fastIOI(); input(); solve(); return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...