제출 #511227

#제출 시각아이디문제언어결과실행 시간메모리
511227blue다리 (APIO19_bridges)C++17
44 / 100
3094 ms11760 KiB
#include <iostream> #include <vector> #include <algorithm> #include <set> using namespace std; using vi = vector<int>; using pii = pair<int, int>; const int rt = 1000; int n, m; vi u, v, w; int q; vi t; vi b, r; vi s, c; struct change { int u; int op; int typ; }; struct disjoint_set { vi parent; vi subtree; vector<change> changes; //node, type(0/1) disjoint_set() { parent = vi(1+n); subtree = vi(1+n, 1); for(int i = 0; i <= n; i++) parent[i] = i; } int root(int u) { if(parent[u] == u) return u; else if(parent[parent[u]] == parent[u]) return parent[u]; else { changes.push_back({u, parent[u], 0}); parent[u] = root(parent[u]); return parent[u]; } } void join(int u, int v) { changes.push_back({-1, -1, -1}); u = root(u); v = root(v); if(u == v) { // cerr << "change rejected\n"; changes.push_back({0, 0, 0}); } else { if(subtree[u] < subtree[v]) swap(u, v); changes.push_back({v, parent[v], 1}); parent[v] = u; subtree[u] += subtree[v]; // changes.push_back(v); // cerr << "making " << u << " parent of " << v << '\n'; } } void rollback() { while(1) { int u = changes.back().u; int op = changes.back().op; int typ = changes.back().typ; changes.pop_back(); if(u == -1) return; if(typ == 1) { subtree[parent[u]] -= subtree[u]; parent[u] = op; } else { parent[u] = op; } } } int reach(int u) { return subtree[root(u)]; } }; int wt(int d) { if(d > 0) { return w[d]; } else { return c[-d]; } } int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); cin >> n >> m; u = v = w = vi(1+m); for(int e = 1; e <= m; e++) cin >> u[e] >> v[e] >> w[e]; cin >> q; t = b = r = s = c = vi(q); for(int j = 0; j < q; j++) { cin >> t[j]; if(t[j] == 1) cin >> b[j] >> r[j]; else cin >> s[j] >> c[j]; } vi ans(q, -1); vi temp_edge_found(1+m, 0); for(int bl = 0; bl <= (q-1)/rt; bl++) { int y = rt*bl; int z = min(rt*(bl+1)-1, q-1); // cerr << "current block = " << y << ' ' << z << '\n'; vi mod(1+m); for(int j = y; j <= z; j++) if(t[j] == 1) mod[b[j]] = 1; vi ops; for(int e = 1; e <= m; e++) if(!mod[e]) ops.push_back(e); for(int j = y; j <= z; j++) if(t[j] == 2) ops.push_back(-j); sort(ops.begin(), ops.end(), [] (int d, int f) { int wd = wt(d), wf = wt(f); if(wd != wf) return wd > wf; else return d > f; }); disjoint_set dsu; for(int o: ops) { // cerr << "\n\n\n"; if(o > 0) { dsu.join(u[o], v[o]); // cerr << "general join: " << o << '\n'; } else { int qr = -o; int curr_ct = 0; // cerr << "answering query : " << qr << '\n'; for(int l = qr-1; l >= y; l--) { if(t[l] == 2) continue; if(temp_edge_found[b[l]]) continue; temp_edge_found[b[l]] = 1; if(r[l] >= c[qr]) { // cerr << "query specific join 1: " << b[l] << '\n'; dsu.join(u[b[l]], v[b[l]]); curr_ct++; } } for(int l = qr+1; l <= z; l++) { // cerr << "l = " << l << '\n'; if(t[l] == 2) continue; if(temp_edge_found[b[l]]) continue; // cerr << "success!\n"; temp_edge_found[b[l]] = 1; // cerr << b[l] << " > " << w[b[l]] << ' ' << c[qr] << '\n'; if(w[b[l]] >= c[qr]) { // cerr << "query specific join 2: " << b[l] << '\n'; dsu.join(u[b[l]], v[b[l]]); curr_ct++; } } ans[qr] = dsu.reach(s[qr]); for(int ct = 0; ct < curr_ct; ct++) { // cerr << "rollback\n"; dsu.rollback(); } for(int l = y; l <= z; l++) { if(t[l] == 1) { temp_edge_found[b[l]] = 0; } } } } for(int l = y; l <= z; l++) { if(t[l] == 1) { w[b[l]] = r[l]; } } } for(int j = 0; j < q; j++) if(t[j] == 2) cout << ans[j] << '\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...