Submission #960312

#TimeUsernameProblemLanguageResultExecution timeMemory
960312alextodoranConstellation 3 (JOI20_constellation3)C++17
0 / 100
5 ms20828 KiB
/** _ _ __ _ _ _ _ _ _ |a ||t ||o d | |o | | __ _| | _ | __| _ | | __ |/_ | __ /__\ / _\| **/ #include <bits/stdc++.h> using namespace std; typedef long long ll; const int N_MAX = 200000; const int M_MAX = 200000; const int LOG_N = 18; int N; int A[N_MAX + 2]; int M; struct Star { int x, y; int cost; }; Star S[N_MAX + 2]; int L[N_MAX + 2], R[N_MAX + 2]; int st[N_MAX + 2], cnt; void get_LR () { cnt = 0; st[0] = 0; for (int i = 1; i <= N; i++) { while (cnt > 0 && A[i] >= A[st[cnt]]) { cnt--; } L[i] = st[cnt] + 1; st[++cnt] = i; } cnt = 0; st[0] = N + 1; for (int i = N; i >= 1; i--) { while (cnt > 0 && A[i] >= A[st[cnt]]) { cnt--; } R[i] = st[cnt] - 1; st[++cnt] = i; } } int node[N_MAX + 2]; int parent[N_MAX + 2]; vector <int> sons[N_MAX + 2]; int anc[N_MAX + 2][LOG_N]; int root; vector <int> stars[N_MAX + 2]; void get_tree () { iota(node + 1, node + N + 1, 1); for (int i = 1; i <= N; i++) { int l = L[i] - 1, r = R[i] + 1; if (1 <= l && r <= N && A[l] == A[r]) { node[r] = node[l]; } if (A[i] == A[i - 1]) { node[i] = node[i - 1]; } } for (int i = 1; i <= N; i++) { int l = L[i] - 1, r = R[i] + 1; parent[node[i]] = (A[l] <= A[r] ? node[l] : node[r]); } for (int u = 1; u <= N; u++) { if (node[u] == u) { sons[parent[u]].push_back(u); anc[u][0] = parent[u]; if (parent[u] == 0) { root = u; } } } for (int k = 1; k < LOG_N; k++) { for (int u = 1; u <= N; u++) { anc[u][k] = anc[anc[u][k - 1]][k - 1]; } } for (int i = 1; i <= M; i++) { int u = S[i].x; for (int k = LOG_N - 1; k >= 0; k--) { if (A[anc[u][k]] < S[i].y) { u = anc[u][k]; } } stars[u].push_back(i); } } int eul[N_MAX + 2], eur[N_MAX + 2]; int curr; void dfs (int u) { eul[u] = ++curr; for (int v : sons[u]) { dfs(v); } eur[u] = curr; } ll max_keep[N_MAX + 2]; ll sum_up[N_MAX + 2]; ll sum_sons_up[N_MAX + 2]; void update (ll Fen[], int pos, ll val) { for (int i = pos; i <= N; i += i & -i) { Fen[i] += val; } } void update (ll Fen[], int l, int r, ll val) { update(Fen, l, val); update(Fen, r + 1, -val); } ll query (ll Fen[], int pos) { ll sum = 0; for (int i = pos; i >= 1; i -= i & -i) { sum += Fen[i]; } return sum; } ll chain_sum (int u) { return query(sum_sons_up, eul[u]) - query(sum_up, eul[u]); } void solve (int u) { ll sum_sons = 0; for (int v : sons[u]) { solve(v); sum_sons += max_keep[v]; } update(sum_sons_up, eul[u], eur[u], sum_sons); max_keep[u] = sum_sons; for (int i : stars[u]) { max_keep[u] = max(max_keep[u], S[i].cost + chain_sum(node[S[i].x])); } update(sum_up, eul[u], eur[u], max_keep[u]); } int main () { ios_base::sync_with_stdio(false); cin.tie(0); cin >> N; for (int x = 1; x <= N; x++) { cin >> A[x]; } A[0] = A[N + 1] = N + 1; cin >> M; for (int i = 1; i <= M; i++) { cin >> S[i].x >> S[i].y >> S[i].cost; } get_LR(); get_tree(); dfs(root); solve(root); ll answer = 0; for (int i = 1; i <= M; i++) { answer += S[i].cost; } answer -= max_keep[root]; cout << answer << "\n"; return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...