제출 #1273311

#제출 시각아이디문제언어결과실행 시간메모리
1273311thuhienne자매 도시 (APIO20_swap)C++20
0 / 100
1 ms572 KiB
#include <bits/stdc++.h> using namespace std; struct Edge { int u, v, w; bool operator<(const Edge &o) const { return w < o.w; } }; struct Node { int parent, size; int deg; // bậc của node int cnt0, cnt1; // số node bậc 1 và bậc 2 trong component nếu là root int l, r; }; struct PersistentDSU { int n; vector<int> root; // root[version] vector<Node> seg; PersistentDSU(int n_) : n(n_) { seg.reserve(40 * n); // phòng đủ bộ nhớ int initRoot = build(1, n); root.push_back(initRoot); } int build(int l, int r) { int id = seg.size(); seg.push_back({}); if (l == r) { seg[id].parent = l; seg[id].size = 1; seg[id].deg = 0; seg[id].cnt0 = 0; seg[id].cnt1 = 0; return id; } int mid = (l + r) / 2; seg[id].l = build(l, mid); seg[id].r = build(mid+1, r); return id; } Node query(int id, int l, int r, int pos) { if (l == r) return seg[id]; int mid = (l + r) / 2; if (pos <= mid) return query(seg[id].l, l, mid, pos); else return query(seg[id].r, mid+1, r, pos); } int update(int prev, int l, int r, int pos, Node val) { int id = seg.size(); seg.push_back(seg[prev]); // copy node if (l == r) { seg[id] = val; return id; } int mid = (l + r) / 2; if (pos <= mid) seg[id].l = update(seg[prev].l, l, mid, pos, val); else seg[id].r = update(seg[prev].r, mid+1, r, pos, val); return id; } int find(int rootId, int u) { Node nu = query(rootId, 1, n, u); if (nu.parent == u) return u; return find(rootId, nu.parent); } int unionSet(int rootId, int u, int v) { u = find(rootId, u); v = find(rootId, v); if (u == v) return rootId; Node nu = query(rootId, 1, n, u); Node nv = query(rootId, 1, n, v); if (nu.size < nv.size) swap(u, v), swap(nu, nv); // v -> u nv.parent = u; int newRoot = update(rootId, 1, n, v, nv); nu.size += nv.size; nu.cnt0 += nv.cnt0; nu.cnt1 += nv.cnt1; newRoot = update(newRoot, 1, n, u, nu); return newRoot; } int incDeg(int rootId, int u) { Node nu = query(rootId, 1, n, u); int r = find(rootId, u); Node nr = query(rootId, 1, n, r); if (nu.deg == 1) nr.cnt0--; // bậc 1 -> 2 if (nu.deg == 0) nr.cnt0++; if (nu.deg == 1) nr.cnt1++; nu.deg++; rootId = update(rootId, 1, n, u, nu); rootId = update(rootId, 1, n, r, nr); return rootId; } // check điều kiện Hamilton path component chứa x,y bool check(int rootId, int x, int y) { int rx = find(rootId, x); int ry = find(rootId, y); if (rx != ry) return false; Node nr = query(rootId, 1, n, rx); return !(nr.cnt1 == nr.size - 2 && nr.cnt0 == 2); } }; int n, m, q; vector<Edge> edges; PersistentDSU *dsu; vector<int> versionRoot; void init(int N, int M, vector<int> U, vector<int> V, vector<int> W) { n = N; m = M; edges.resize(m); for (int i = 0; i < m; i++) { edges[i] = {U[i]+1, V[i]+1, W[i]}; // shift sang 1-based } sort(edges.begin(), edges.end()); dsu = new PersistentDSU(n); versionRoot.resize(m+1); versionRoot[0] = dsu->root[0]; for (int i = 1; i <= m; i++) { int rootId = versionRoot[i-1]; rootId = dsu->incDeg(rootId, edges[i-1].u); rootId = dsu->incDeg(rootId, edges[i-1].v); rootId = dsu->unionSet(rootId, edges[i-1].u, edges[i-1].v); versionRoot[i] = rootId; } } int getMinimumFuelCapacity(int X, int Y) { X++, Y++; int l = 1, r = m, ans = -1; while (l <= r) { int mid = (l + r) / 2; if (dsu->check(versionRoot[mid], X, Y)) { ans = edges[mid-1].w; r = mid - 1; } else { l = mid + 1; } } return 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...