Submission #1216121

#TimeUsernameProblemLanguageResultExecution timeMemory
1216121duckindog도로 개발 (JOI15_road_development)C++20
100 / 100
176 ms31296 KiB
#include <bits/stdc++.h> using namespace std; const int N = 300'000 + 10; int n, q; struct Edge { int type, u, v; friend istream& operator >> (istream& is, Edge& rhs) { return is >> rhs.type >> rhs.u >> rhs.v; } } edge[N]; struct DSU { int id[N]; void init() { memset(id, -1, sizeof id); } int root(int u) { return id[u] < 0 ? u : id[u] = root(id[u]); } void join(int u, int v) { u = root(u); v = root(v); if (u == v) return; id[u] += id[v]; id[v] = u; } bool isCon(int u, int v) { return root(u) == root(v); } } T, D; vector<int> ad[N]; int f[N][17]; int st[N], ed[N], timer; void dfs(int u, int p = -1) { st[u] = ++timer; for (int i = 1; i <= 16; ++i) f[u][i] = f[f[u][i - 1]][i - 1]; for (const auto& v : ad[u]) { if (v == p) continue; f[v][0] = u; dfs(v, u); } ed[u] = timer; } inline bool anc(int u, int v) { return st[u] <= st[v] && ed[u] >= ed[v]; } int lca(int u, int v) { if (anc(u, v)) return u; if (anc(v, u)) return v; for (int i = 16; i >= 0; --i) if (!anc(f[u][i], v)) u = f[u][i]; return f[u][0]; } namespace BIT { int bit[N]; inline void upd(int i, int x) { for (; i <= n; i += i & -i) bit[i] += x; } inline int que(int i) { int ret = 0; for (; i; i -= i & -i) ret += bit[i]; return ret; } inline void upd(int l, int r, int x) { upd(l, x); upd(r + 1, -x); } } int32_t main() { cin.tie(0)->sync_with_stdio(0); cin >> n >> q; for (int i = 1; i <= q; ++i) cin >> edge[i]; T.init(); for (int i = 1; i <= q; ++i) { const auto& [type, u, v] = edge[i]; if (type == 1) { if (!T.isCon(u, v)) { ad[u].push_back(v); ad[v].push_back(u); T.join(u, v); } } } for (int i = 1; i <= n; ++i) if (!st[i]) dfs(f[i][0] = i); for (int i = 1; i <= n; ++i) if (f[i][0] != i) BIT::upd(st[i], ed[i], 1); T.init(); D.init(); for (int i = 1; i <= q; ++i) { auto [type, u, v] = edge[i]; if (anc(v, u)) swap(u, v); if (type == 1) { if (!T.isCon(u, v)) { T.join(u, v); } else { for (int turn = 0; turn <= 1; ++turn) { for (;;) { int x = D.root(v); if (anc(x, u)) break; D.join(f[x][0], x); BIT::upd(st[x], ed[x], -1); } swap(u, v); } } } else { if (!T.isCon(u, v)) cout << -1 << "\n"; else cout << BIT::que(st[u]) + BIT::que(st[v]) - 2 * BIT::que(st[lca(u, v)]) << "\n"; } } }
#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...