제출 #1245455

#제출 시각아이디문제언어결과실행 시간메모리
1245455countless던전 (IOI21_dungeons)C++20
0 / 100
7090 ms23540 KiB
#include "dungeons.h" #include <bits/stdc++.h> using namespace std; #pragma GCC optimize("O3") typedef long long ll; typedef long double ld; #define sp <<" "<< #define endl "\n" const int MAXN = 4e5+5; const int LOGN = 25; int N; vector<int> S, P, W, L, end, par; vector<ll> trav, dep; vector<vector<pair<int, int>>> adj; vector<vector<int>> up; vector<vector<ll>> sum; int find(int u) { if (u == par[u]) return u; return par[u] = find(par[u]); } void unite(int u, int v) { u = find(u), v = find(v); if (u == v) return; if (dep[u] > dep[v]) swap(u, v); par[v] = u; } void init(int n, vector<int> s, vector<int> p, vector<int> w, vector<int> l) { N = n, S = s, P = p, W = w, L = l; trav.resize(N+1), adj.resize(N+1), dep.resize(N+1), par.resize(N+1); up.assign(LOGN, vector<int>(N+1)); sum.assign(LOGN, vector<ll>(N+1)); iota(par.begin(), par.end(), 0); using edge = tuple<ll, int, int>; vector<edge> edges; for (int i = 0; i < N; i++) { adj[W[i]].emplace_back(i, S[i]); edges.emplace_back(S[i], i, W[i]); } sort(edges.begin(), edges.end()); auto pre = [&](auto &&pre, int u, int p) -> void { for (auto &[v, w] : adj[u]) { if (v != p) { trav[v] = trav[u] + w; dep[v] = dep[u] + 1; pre(pre, v, u); } } }; pre(pre, N, -1); vector<bool> proc(N+1); int lo = 0, hi = 0; while (lo < N) { hi = lo; while (hi < N and get<0>(edges[lo]) == get<0>(edges[hi])) hi++; for (int i = lo; i < hi; i++) { auto [w, u, v] = edges[i]; if (proc[u] or proc[v] or u == N or v == N) continue; unite(u, v); } for (int i = lo; i < hi; i++) { auto [w, u, v] = edges[i]; proc[u] = proc[v] = true; } lo = hi; } for (int i = 0; i <= N; i++) { up[0][i] = (i != N ? L[i] : N); sum[0][i] = (i != N ? P[i] : 0); } for (int j = 1; j < LOGN; j++) { for (int i = 0; i <= N; i++) { up[j][i] = up[j-1][ up[j-1][i] ]; sum[j][i] = sum[j-1][i] + sum[j-1][ up[j-1][i] ]; } } return; } ll simulate(int x, int z) { ll at = x, ans = z; cerr << endl << endl << endl; while (true) { for (int j = LOGN-1; j >= 0; j--) { // cerr << at sp ans sp sum[j][at] sp S[find(at)] << endl; if (up[j][at] != N and ans + sum[j][at] < S[find(at)]) { ans += sum[j][at]; at = up[j][at]; } } // cerr << at sp ans << endl; if (up[0][at] == N or ans < S[find(at)]) { ans += sum[0][at]; at = up[0][at]; } if (at == N) return trav[at] + ans; if (ans >= S[find(at)]) { ans += S[at]; at = W[at]; } } return trav[at] + ans; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...