Submission #172618

#TimeUsernameProblemLanguageResultExecution timeMemory
172618rama_pangBridges (APIO19_bridges)C++14
100 / 100
2565 ms7316 KiB
#include <bits/stdc++.h> using namespace std; const int BLOCK = 900; struct RollbackDSU { vector<int> root; // parent vector<int> sz; // size vector<pair<int, int>> operations; // (modified_id, size[id]). If size[id] == -1, then the parent changes void init(int n) { sz.assign(n, 1); root.assign(n, 0); iota(begin(root), end(root), 0); } int find(int n) { while (root[n] != n) { n = root[n]; } return n; } bool join(int a, int b, bool revert = false) { a = find(a); b = find(b); if (a == b) { return false; } if (sz[a] < sz[b]) { swap(a, b); } if (revert) { operations.emplace_back(b, -1); // b's parent changes operations.emplace_back(a, sz[a]); // a's previous size } sz[a] += sz[b]; root[b] = a; return true; } void rollback() { reverse(begin(operations), end(operations)); for (auto& op : operations) { if (op.second == -1) { root[op.first] = op.first; } else { sz[op.first] = op.second; } } operations.clear(); } int getSize(int n) { return sz[find(n)]; } }; struct Edge { int u, v, weight; Edge(int u, int v, int w) : u(u), v(v), weight(w) {} bool operator<(const Edge& o) const { return weight > o.weight; } }; struct Query { int start, weight, time; Query(int s, int w, int t) : start(s), weight(w), time(t) {} bool operator<(const Query& o) const { return weight > o.weight; } }; int main() { ios::sync_with_stdio(0); cin.tie(0), cout.tie(0); int n, m; cin >> n >> m; vector<Edge> edge; vector<pair<int, int>> update(m, make_pair(-1, -1)); // (weight, update_time) for (int i = 0; i < m; i++) { int u, v, w; cin >> u >> v >> w; u--, v--; edge.emplace_back(u, v, w); } int q; cin >> q; RollbackDSU DSU; vector<pair<int, int>> ans; // (time, answer) for (int qi = 0; qi < q; qi += BLOCK) { vector<Query> query; // query: (time, start, weight) vector<tuple<int, int, int, int>> changed; // (id, weight, time1, time2) -> the id-th edge has weight for time peirod [time1, time2] vector<Edge> unchanged; // ids of unchanged edges DSU.init(n); for (int i = qi; i < qi + BLOCK && i < q; i++) { int t, a, b; cin >> t >> a >> b; a--; if (t == 1) { if (update[a] == make_pair(-1, -1)) { update[a].first = edge[a].weight; } changed.emplace_back(a, update[a].first, update[a].second, i - 1); // the current weight lasts between (t1, t2) update[a] = {b, i}; } else if (t == 2) { query.emplace_back(a, b, i); } } for (int i = 0; i < m; i++) { if (update[i] != make_pair(-1, -1)) { changed.emplace_back(i, update[i].first, update[i].second, qi + BLOCK); // Update original edge's weight with latest update edge[i].weight = update[i].first; update[i] = make_pair(-1, -1); } else { unchanged.emplace_back(edge[i]); } } sort(begin(unchanged), end(unchanged)); sort(begin(query), end(query)); for (int i = 0, j = 0; i < query.size(); i++) { // O(BLOCK) iterations while (j < unchanged.size() && unchanged[j].weight >= query[i].weight) { DSU.join(unchanged[j].u, unchanged[j].v); j++; } for (auto& c : changed) { // O(BLOCK log n) int id, w, t1, t2; tie(id, w, t1, t2) = c; if (t1 <= query[i].time && query[i].time <= t2 && w >= query[i].weight) { DSU.join(edge[id].u, edge[id].v, true); } } ans.emplace_back(query[i].time, DSU.getSize(query[i].start)); DSU.rollback(); } } sort(begin(ans), end(ans)); for (auto& i : ans) { cout << i.second << "\n"; } return 0; }

Compilation message (stderr)

bridges.cpp: In function 'int main()':
bridges.cpp:136:34: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
         for (int i = 0, j = 0; i < query.size(); i++) { // O(BLOCK) iterations
                                ~~^~~~~~~~~~~~~~
bridges.cpp:137:22: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
             while (j < unchanged.size() && unchanged[j].weight >= query[i].weight) {
                    ~~^~~~~~~~~~~~~~~~~~
#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...