제출 #1125655

#제출 시각아이디문제언어결과실행 시간메모리
1125655ShadowSharkRigged Roads (NOI19_riggedroads)C++20
100 / 100
298 ms85896 KiB
#include <bits/stdc++.h> using namespace std; const int maxN = 3e5 + 5; vector<pair<int, int>> adj[maxN]; pair<int, int> edge[maxN]; int par[maxN], belong[maxN], ans[maxN], ask[maxN]; int depth[maxN], pos[maxN], RMQ[21][2 * maxN], tick = 0; void dfs(int u, int pre) { RMQ[0][++tick] = u; pos[u] = tick; for (auto it: adj[u]) { int v = it.first, id = it.second; if (v == pre) continue; belong[v] = id; par[v] = u; depth[v] = depth[u] + 1; dfs(v, u); RMQ[0][++tick] = u; } } /// DSU int pre[maxN], sz[maxN], Top[maxN]; int find_set(int u) { return (u == pre[u]) ? u : pre[u] = find_set(pre[u]); } void union_set(int u, int v) { u = find_set(u); v = find_set(v); if (u == v) return ; if (sz[u] < sz[v]) swap(u, v); pre[v] = u; sz[u] += sz[v]; if (depth[Top[u]] > depth[Top[v]]) Top[u] = Top[v]; } int min_depth(int x, int y) {return (depth[x] < depth[y]) ? x : y;}; int getLCA(int u, int v) { int l = pos[u], r = pos[v]; if (l > r) swap(l, r); int k = 31 - __builtin_clz(r - l + 1); return min_depth(RMQ[k][l], RMQ[k][r - (1 << k) + 1]); } int main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); int n, m; cin >> n >> m; for (int i = 1; i <= m; i++) { int u, v; cin >> u >> v; edge[i] = {u, v}; } for (int i = 1; i < n; i++) { int id; cin >> id; auto [u, v] = edge[id]; ask[id] = 1; adj[u].push_back({v, id}); adj[v].push_back({u, id}); } depth[1] = 1; dfs(1, 1); for (int j = 1; (1 << j) <= tick; j++) for (int i = 1; i <= tick - (1 << j) + 1; i++) RMQ[j][i] = min_depth(RMQ[j - 1][i], RMQ[j - 1][i + (1 << (j - 1))]); for (int i = 1; i <= n; i++) { pre[i] = i; sz[i] = 1; Top[i] = i; } int curr_idx = 1; vector<int> rem, add; for (int i = 1; i <= m; i++) { if (ans[i]) continue; auto [u, v] = edge[i]; int lca = getLCA(u, v); /// All edge not visited int tick = 0; while (true) { u = find_set(u); rem.push_back(u); if (depth[Top[u]] <= depth[lca]) break; add.push_back(belong[Top[u]]); u = par[Top[u]]; } while (true) { v = find_set(v); rem.push_back(v); if (depth[Top[v]] <= depth[lca]) break; add.push_back(belong[Top[v]]); v = par[Top[v]]; } if (add.size()) { sort(add.begin(), add.end()); for (auto x: add) ans[x] = curr_idx++; } for (auto x: rem) union_set(x, u); rem.clear(); add.clear(); if (!ask[i]) ans[i] = curr_idx++; } for (int i = 1; i <= m; i++) cout << ans[i] << ' '; return 0; }
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...