제출 #930752

#제출 시각아이디문제언어결과실행 시간메모리
930752rxlfd314다리 (APIO19_bridges)C++17
100 / 100
1472 ms7428 KiB
#pragma GCC optimize("O3,unroll-loops") #pragma GCC target("avx2") #include <bits/stdc++.h> using namespace std; using ari2 = array<int, 2>; using ari3 = array<int, 3>; #define vt vector #define size(x) (int((x).size())) #define all(x) begin(x), end(x) #define REP(a, b, c, d) for (int a = (b); (d) > 0 ? a <= (c) : a >= (c); a += (d)) #define FOR(a, b, c) REP(a, b, c, 1) #define ROF(a, b, c) REP(a, b, c, -1) signed main() { #ifndef DEBUG ios_base::sync_with_stdio(false); cin.tie(nullptr); #endif int N, M; cin >> N >> M; int A[M], B[M], D[M]; FOR(i, 0, M-1) cin >> A[i] >> B[i] >> D[i], A[i]--, B[i]--; constexpr int BSZ = 1050; int Q; cin >> Q; int ans[Q]; memset(ans, -1, sizeof(ans)); REP(q, 0, Q-1, BSZ) { vt<ari3> qrys, upds; bool bad[M] = {}; int edge_cnt = M; FOR(i, q, min(Q, q+BSZ)-1) { int qt, a, b; cin >> qt >> a >> b; if (qt == 1) upds.push_back({i, --a, b}), edge_cnt -= !bad[a], bad[a] = true; else qrys.push_back({b, --a, i}); } sort(all(qrys), greater<ari3>()); reverse(all(upds)); const int upd_size = size(upds); int edges[edge_cnt], edge_ptr = 0; FOR(i, 0, M-1) { if (bad[i]) upds.push_back({-1, i, D[i]}); else edges[edge_ptr++] = i; } sort(edges, edges + edge_cnt, [&](const int &a, const int &b) { return D[a] < D[b]; }); int uf[N], op_ptr = 0; ari2 ops[N]; memset(uf, -1, sizeof(uf)); function<int(int)> find2 = [&](int i) { return uf[i] < 0 ? i : uf[i] = find2(uf[i]); }; auto find = [&](int i, bool b) { if (!b) return find2(i); while (uf[i] >= 0) i = uf[i]; return i; }; auto unite = [&](int a, int b, bool c) { if ((a = find(a, c)) == (b = find(b, c))) return false; if (uf[a] > uf[b]) swap(a, b); if (c) ops[op_ptr++] = {b, uf[b]}; uf[a] += uf[b]; uf[b] = a; return true; }; auto rollback = [&]() { auto [b, v] = ops[--op_ptr]; uf[uf[b]] -= v; uf[b] = v; }; bool seen[M] = {}; for (auto [w, i, qi] : qrys) { while (edge_ptr && D[edges[edge_ptr-1]] >= w) { edge_ptr--; unite(A[edges[edge_ptr]], B[edges[edge_ptr]], 0); } int cnt = 0; for (auto [ui, b, k] : upds) { if (ui > qi) continue; if (!seen[b] && k >= w) cnt += unite(A[b], B[b], 1); seen[b] = true; } ans[qi] = -uf[find(i, 1)]; while (cnt--) rollback(); FOR(j, upd_size, size(upds)-1) seen[upds[j][1]] = false; } FOR(i, 0, upd_size-1) { // cOnStAnT oPtImIsAtIoN auto [ui, b, k] = upds[i]; if (seen[b]) continue; D[b] = k; seen[b] = true; } } FOR(i, 0, Q-1) if (~ans[i]) cout << ans[i] << '\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...
#Verdict Execution timeMemoryGrader output
Fetching results...