제출 #898054

#제출 시각아이디문제언어결과실행 시간메모리
898054phoenix다리 (APIO19_bridges)C++17
100 / 100
1567 ms23504 KiB
#include<bits/stdc++.h> using namespace std; using ll = long long; const int N = 50000 + 10; const int M = 100000 + 10; const int Q = 100000 + 10; const int B = 800; struct DSU { vector<int> p; vector<int> r; void init(int n) { p.assign(n + 1, 0); r.assign(n + 1, 1); iota(p.begin(), p.end(), 0); } int find(int x) { return p[x] = (p[x] == x ? x : find(p[x])); } void unite(int u, int v) { u = find(u); v = find(v); if(u == v) return; if(r[u] < r[v]) swap(u, v); r[u] += r[v]; p[v] = u; } }; struct query { int s, w, i; }; struct upd { int b, r, i; }; int n, m, q_len; int d[M + 1]; vector<pair<int, int>> edges = {{0, 0}}; vector<query> q[Q / B + 10]; vector<upd> u[Q / B + 10]; int MAX_W = 0; vector<int> e_sorted[M + Q + 10]; void compress() { map<int, int> mp; for(int i = 1; i <= m; i++) mp[d[i]] = 1; for(int i = 0; i <= (q_len - 1) / B; i++) { for(auto c : q[i]) mp[c.w] = 1; for(auto c : u[i]) mp[c.r] = 1; } for(auto &c : mp) c.second = MAX_W ++; for(int i = 1; i <= m; i++) d[i] = mp[d[i]]; for(int i = 0; i <= (q_len - 1) / B; i++) { for(auto &c : q[i]) c.w = mp[c.w]; for(auto &c : u[i]) c.r = mp[c.r]; } } vector<int> g[N]; DSU ds; bool vis[N]; int dfs(int s) { vis[s] = true; int res = ds.r[s]; for(int to : g[s]) { if(vis[to]) continue; res += dfs(to); } return res; } int main() { ios::sync_with_stdio(0); cin.tie(0);cout.tie(0); // freopen("test.txt", "r", stdin); cin >> n >> m; for(int i = 1; i <= m; i++) { int u, v; cin >> u >> v >> d[i]; edges.push_back({u, v}); } cin >> q_len; vector<int> res(q_len, -1); for(int i = 0; i < q_len; i++) { int type; cin >> type; if(type == 1) { int b, r; cin >> b >> r; u[i / B].push_back({b, r, i}); } else { int s, w; cin >> s >> w; q[i / B].push_back({s, w, i}); } } compress(); for(int buck = 0; buck <= (q_len - 1) / B; buck++) { int d_changed[m + 1] = {}; bool is_changed[m + 1] = {}; vector<int> changed; for(auto c : u[buck]) { if(!is_changed[c.b]) changed.push_back(c.b); is_changed[c.b] = true; d_changed[c.b] = d[c.b]; } for(int i = 1; i <= m; i++) { if(!is_changed[i]) { e_sorted[d[i]].push_back(i); } } sort(q[buck].begin(), q[buck].end(), [](query a, query b) { return (a.w > b.w); }); ds.init(n + 1); int cur_query = 0; for(int minw = MAX_W - 1; minw >= 0; minw--) { for(int e_i : e_sorted[minw]) ds.unite(edges[e_i].first, edges[e_i].second); while(cur_query < (int)q[buck].size() && q[buck][cur_query].w >= minw) { auto [s, w, inx] = q[buck][cur_query]; for(auto cur_up : u[buck]) { if(cur_up.i > inx) break; d_changed[cur_up.b] = cur_up.r; } for(int e_i : changed) { if(d_changed[e_i] < w) continue; auto [u, v] = edges[e_i]; u = ds.find(u), v = ds.find(v); g[u].push_back(v); g[v].push_back(u); } s = ds.find(s); res[inx] = dfs(s); for(int e_i : changed) { d_changed[e_i] = d[e_i]; auto [u, v] = edges[e_i]; u = ds.find(u), v = ds.find(v); vis[u] = 0; vis[v] = 0; g[u].clear(); g[v].clear(); } vis[s] = 0; cur_query++; } e_sorted[minw].clear(); } for(auto upd : u[buck]) d[upd.b] = upd.r; } for(int i = 0; i < q_len; i++) if(res[i] != -1) cout << res[i] << '\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...