제출 #563629

#제출 시각아이디문제언어결과실행 시간메모리
563629brunovsky다리 (APIO19_bridges)C++17
100 / 100
2518 ms9792 KiB
#include <bits/stdc++.h> #ifdef LOCAL #include "code/formatting.hpp" #else #define debug(...) (void)0 #endif using namespace std; struct disjoint_set_rollback { int N, S; vector<int> next; vector<pair<int, int>> history; explicit disjoint_set_rollback(int N = 0) : N(N), S(N), next(N, -1) {} void assign(int n) { *this = disjoint_set_rollback(n); } void reset() { *this = disjoint_set_rollback(N); } bool same(int i, int j) { return find(i) == find(j); } bool unit(int i) { return next[i] == -1; } bool root(int i) { return next[i] < 0; } int size(int i) { return -next[i]; } int time() const { return history.size(); } void rollback(int t) { int i = time(); while (i > t) { i--, next[history[i].first] = history[i].second; i--, next[history[i].first] = history[i].second; S++; } history.resize(t); } int find(int i) { while (next[i] >= 0) { i = next[i]; } return i; } bool join(int i, int j) { i = find(i); j = find(j); if (i != j) { if (size(i) < size(j)) { swap(i, j); } history.emplace_back(i, next[i]); history.emplace_back(j, next[j]); next[i] += next[j]; next[j] = i, S--; return true; } return false; } }; auto filter_pairs(const vector<array<int, 2>>& a) { int N = a.size(); vector<array<int, 2>> b; for (int i = 0; i < N; i++) { if (i == 0 || a[i][0] != a[i - 1][0]) { b.push_back(a[i]); } } return b; } int main() { ios::sync_with_stdio(false), cin.tie(nullptr); int N, M; cin >> N >> M; vector<array<int, 3>> graph(M); for (int i = 0; i < M; i++) { int u, v, d; cin >> u >> v >> d, u--, v--; graph[i] = {d, u, v}; } auto edge_compare = [&](int a, int b) { return make_pair(graph[a][0], a) > make_pair(graph[b][0], b); }; set<int, decltype(edge_compare)> edges(edge_compare); for (int e = 0; e < M; e++) { edges.insert(e); } int Q; cin >> Q; vector<array<int, 3>> queries(Q); for (int q = 0; q < Q; q++) { int t, a, b; cin >> t >> a >> b, a--; queries[q] = {t, a, b}; } const int B = sqrt(N + M); vector<int> ans(Q), weight(M); disjoint_set_rollback dsu(N); for (int L = 0, R = min(B, Q); L < Q; L = R, R = min(Q, R + B)) { vector<int> upds, asks; vector<array<int, 2>> bans; for (int q = L; q < R; q++) { auto [t, a, b] = queries[q]; if (t == 1) { upds.push_back(q); bans.push_back({a, q}); weight[a] = -1; } else if (t == 2) { asks.push_back(q); } else { assert(false); } } sort(begin(asks), end(asks), [&](int i, int j) { return make_pair(queries[i][2], j) > make_pair(queries[j][2], i); }); sort(begin(bans), end(bans)); bans = filter_pairs(bans); for (auto [e, _] : bans) { edges.erase(e); } auto it = edges.begin(); int U = upds.size(); for (int q : asks) { auto [tq, s, w] = queries[q]; while (it != edges.end() && graph[*it][0] >= w) { auto [_, a, b] = graph[*it++]; dsu.join(a, b); } int time = dsu.time(); for (int u = 0; u < U && upds[u] < q; u++) { auto [_, e, c] = queries[upds[u]]; weight[e] = c; } for (auto [e, t] : bans) { int c = q < t ? graph[e][0] : weight[e]; auto [_, a, b] = graph[e]; if (c >= w) { dsu.join(a, b); } } ans[q] = dsu.size(dsu.find(s)); dsu.rollback(time); } for (int q : upds) { auto [_, e, w] = queries[q]; edges.erase(e), graph[e][0] = w, edges.insert(e); weight[e] = 0; } dsu.rollback(0); } for (int q = 0; q < Q; q++) { if (ans[q] > 0) { cout << ans[q] << '\n'; } } return 0; } // sqrt rebuilds
#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...