Submission #854923

#TimeUsernameProblemLanguageResultExecution timeMemory
854923JustInCaseBridges (APIO19_bridges)C++17
59 / 100
3049 ms4912 KiB
#include <algorithm> #include <cassert> #include <iostream> #include <stack> #include <vector> using namespace std; const int BLOCK_SIZE = 225; struct edge { int u, v, w; static bool compDecrW(edge e1, edge e2) { return e1.w >= e2.w; } }; struct update { int e, w; }; struct query { int id; int v, w; static bool compDecrW(query q1, query q2) { return q1.w >= q2.w; } }; struct rollback_dsu { struct change { int oldRoot, newRoot; }; vector<int> parent; vector<int> compSize; stack<change> changes; rollback_dsu(int cntNodes) { parent.resize(cntNodes); compSize.resize(cntNodes, 1); for (int i = 0; i < cntNodes; i++) { parent[i] = i; } } int findRoot(int x) { while (parent[x] != x) x = parent[x]; return x; } void unite(int x, int y) { int rootX = findRoot(x); int rootY = findRoot(y); if (rootX == rootY) return; if (compSize[rootX] <= compSize[rootY]) { parent[rootX] = rootY; compSize[rootY] += compSize[rootX]; changes.push(change{rootX, rootY}); } else { parent[rootY] = rootX; compSize[rootX] += compSize[rootY]; changes.push(change{rootY, rootX}); } } void markAsStable() { while (!changes.empty()) changes.pop(); } void rollbackToStable() { while (!changes.empty()) { auto [oldRoot, newRoot] = changes.top(); changes.pop(); parent[oldRoot] = oldRoot; compSize[newRoot] -= compSize[oldRoot]; } } }; int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); int n, m; cin >> n >> m; vector<edge> edges(m); for (int i = 0; i < m; i++) { int u, v, w; cin >> u >> v >> w; u--; v--; edges[i] = edge{u, v, w}; } int q; cin >> q; vector<bool> changed(m, false); for (int i = 0; i < q; i += BLOCK_SIZE) { vector<int> t(min(BLOCK_SIZE, q - i)); vector<update> updates; vector<query> queries; fill(changed.begin(), changed.end(), false); for (int j = 0; j < min(BLOCK_SIZE, q - i); j++) { cin >> t[j]; if (t[j] == 1) { int e, w; cin >> e >> w; e--; updates.push_back(update{e, w}); changed[e] = true; } else { int v, w; cin >> v >> w; v--; queries.push_back(query{(int)queries.size(), v, w}); } } vector<vector<edge>> additionalEdges(queries.size()); int queryInd = 0, updateInd = 0; for (int j = 0; j < min(BLOCK_SIZE, q - i); j++) { if (t[j] == 1) { edges[updates[updateInd].e].w = updates[updateInd].w; updateInd++; } else { assert(queryInd < queries.size()); for (auto u : updates) { if (edges[u.e].w >= queries[queryInd].w) additionalEdges[queryInd].push_back(edges[u.e]); } queryInd++; } } vector<edge> unchanged; for (int j = 0; j < m; j++) { if (!changed[j]) unchanged.push_back(edges[j]); } sort(unchanged.begin(), unchanged.end(), [](edge e1, edge e2) { return e1.w > e2.w; }); sort(queries.begin(), queries.end(), [](query q1, query q2) { return q1.w > q2.w; }); auto dsu = rollback_dsu(n); int edgePtr = 0; vector<int> ans(queries.size()); for (int j = 0; j < queries.size(); j++) { while (edgePtr < unchanged.size() && unchanged[edgePtr].w >= queries[j].w) { dsu.unite(unchanged[edgePtr].u, unchanged[edgePtr].v); edgePtr++; } dsu.markAsStable(); // while (!(queries[j].id >= 0 && queries[j].id < additionalEdges.size())) //; for (auto e : additionalEdges[queries[j].id]) { dsu.unite(e.u, e.v); } assert(queries[j].id >= 0 && queries[j].id < ans.size()); ans[queries[j].id] = dsu.compSize[dsu.findRoot(queries[j].v)]; dsu.rollbackToStable(); } for (auto x : ans) { cout << x << endl; } } }

Compilation message (stderr)

In file included from /usr/include/c++/10/cassert:44,
                 from bridges.cpp:2:
bridges.cpp: In function 'int main()':
bridges.cpp:143:25: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<query>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  143 |         assert(queryInd < queries.size());
      |                ~~~~~~~~~^~~~~~~~~~~~~~~~
bridges.cpp:167:23: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<query>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  167 |     for (int j = 0; j < queries.size(); j++) {
      |                     ~~^~~~~~~~~~~~~~~~
bridges.cpp:168:22: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<edge>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  168 |       while (edgePtr < unchanged.size() &&
      |              ~~~~~~~~^~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/10/cassert:44,
                 from bridges.cpp:2:
bridges.cpp:182:50: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  182 |       assert(queries[j].id >= 0 && queries[j].id < ans.size());
#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...