Submission #1118616

#TimeUsernameProblemLanguageResultExecution timeMemory
1118616stefanneaguBridges (APIO19_bridges)C++17
59 / 100
3051 ms10928 KiB
#include <bits/stdc++.h> using namespace std; const int nmax = 1e5 + 1; int nra = 1; int bit[nmax]; int n, m; int root[nmax], sz[nmax]; int mr[nmax], ms[nmax]; struct DSU { void init() { for(int i = 1; i <= n; i++) { root[i] = i; sz[i] = 1; } } int find(int a) { if(root[a] == a) { return a; } return root[a] = find(root[a]); } void unite(int a, int b) { if(a == b) { return; } if(sz[a] > sz[b]) { swap(a, b); } root[a] = b; sz[b] += sz[a]; } int mfind(int a) { if(bit[a] != nra) { bit[a] = nra; mr[a] = find(a); ms[a] = sz[find(a)]; // cout << "? " << a << " " << mr[a] << " " << ms[a] << '\n'; } if(mr[a] == a) { return a; } return mr[a] = mfind(mr[a]); } void munite(int a, int b) { if(a == b) { return; } if(ms[a] > ms[b]) { swap(a, b); } mr[a] = b; ms[b] += ms[a]; } }; struct str { int a, b, c; }; struct special { int t, a, b, c; }; vector<str> qry, upd, edges; int ans[nmax], mark[nmax]; int pas = 1; bool cmp(special x, special y) { if(x.c != y.c) { return x.c > y.c; } return x.t < y.t; } bool cmp2(str x, str y) { return x.c < y.c; } void solve() { // cout << "START\n"; vector<special> curr; vector<pair<int, int>> unsafe; for(int i = 1; i <= m; i++) { if(mark[i] != pas) { curr.push_back({0, edges[i].a, edges[i].b, edges[i].c}); } else { // cout << "unsafe: " << edges[i].a << " " << edges[i].b << '\n'; unsafe.push_back({i, edges[i].c}); } } for(auto it : qry) { curr.push_back({1, it.a, it.c, it.b}); } sort(curr.begin(), curr.end(), cmp); DSU ds; ds.init(); for(auto _ : curr) { int t = _.t, a = _.a, b = _.b, c = _.c; // cout << "! " << t << " " << a << " " << b << " " << c << '\n'; if(t == 0) { // unite ds.unite(ds.find(a), ds.find(b)); } else { swap(b, c); // query for(auto it : upd) { if(it.c <= c) { edges[it.a].c = it.b; } } for(auto it : unsafe) { if(edges[it.first].c >= b) { // cout << "xtra: " << edges[it.first].a << " " << edges[it.first].b << '\n'; ds.munite(ds.mfind(edges[it.first].a), ds.mfind(edges[it.first].b)); } edges[it.first].c = it.second; } ans[c] = ms[ds.mfind(a)]; nra++; // cout << ans[c] << '\n'; } } // cout << "__\n"; pas++; sort(upd.begin(), upd.end(), cmp2); for(auto it : upd) { edges[it.a].c = it.b; } } int32_t main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); cin >> n >> m; edges.push_back({-1, -1, -1}); for(int i = 1; i <= m; i++) { int a, b, c; cin >> a >> b >> c; if(a > b) { swap(a, b); } edges.push_back({a, b, c}); } int q; cin >> q; int block = sqrt(q); for(int i = 1; i <= q; i++) { int t, a, b; cin >> t >> a >> b; if(t == 1) { // update mark[a] = pas; // cout << ">>" << a << " " << edges[a].a << " " << edges[a].b << "\n"; upd.push_back({a, b, i}); } else { // query qry.push_back({a, b, i}); } if(i % block == 0 || i == q) { solve(); upd.clear(); qry.clear(); } } for(int i = 1; i <= q; i++) { if(ans[i] != 0) { cout << ans[i] << "\n"; } } return 0; }
#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...