제출 #1210856

#제출 시각아이디문제언어결과실행 시간메모리
1210856dubabuba다리 (APIO19_bridges)C++17
14 / 100
3096 ms10660 KiB
#include <bits/stdc++.h> using namespace std; const int mxn = 1e5 + 100; const int BLOCK_sz = 1500; typedef pair<int, int> pii; #define ff first #define ss second #define MP make_pair struct edge { int id, w, u, v; edge() : id(0), w(0), u(0), v(0) {} edge(int id, int u, int v, int w) : id(id), w(w), u(u), v(v) {} const friend bool operator < (const edge e1, const edge e2) { if(e1.w != e2.w) return e1.w > e2.w; return e1.id < e2.id; } }; struct query { int id, u, w; query() : id(0), u(0), w(0) {} query(int id, int u, int w) : id(id), u(u), w(w) {} const friend bool operator < (const query q1, const query q2) { if(q1.w != q2.w) return q1.w > q2.w; return q1.id < q2.id; } }; struct DSU { const int N = 5e4 + 10; int par[mxn]; stack<pair<pii, pii>> hist; DSU() { memset(par, -1, sizeof par); while(hist.size()) hist.pop(); } void init() { memset(par, -1, sizeof par); while(hist.size()) hist.pop(); } int parent(int u) { while(par[u] > 0) u = par[u]; return u; } void unite(int u, int v) { u = parent(u); v = parent(v); if(u == v) return; if(par[u] > par[v]) swap(u, v); hist.push(MP(MP(u, par[u]), MP(v, par[v]))); par[u] += par[v]; par[v] = u; } void roll_back(int sz) { while(hist.size() > sz) { int u, v, pu, pv; tie(u, pu) = hist.top().ff; tie(v, pv) = hist.top().ss; par[u] = pu; par[v] = pv; hist.pop(); } } }; int type[mxn], n, m, q; vector<pii> query(mxn); vector<pii> edges(mxn); int weight[mxn], ans[mxn]; set<edge> SET; int main() { #ifdef LOCAL auto TIME_st = chrono::steady_clock::now(); #endif cin >> n >> m; for(int i = 1; i <= m; i++) { int u, v, w; cin >> u >> v >> w; SET.insert(edge(i, u, v, w)); weight[i] = w; edges[i] = MP(u, v); } cin >> q; for(int i = 0; i < q; i++) { cin >> type[i] >> query[i].ff >> query[i].ss; } function<void(int)> eraser = [&](int i) { SET.erase(edge(i, edges[i].ff, edges[i].ss, weight[i])); }; // function<void(int, int)> connect = [&](int u, int v) { azaa.uni }; for(int L = 0; L < q; L += BLOCK_sz) { int R = min(q, L + BLOCK_sz); vector<int> upt, ask; for(int i = L; i < R; i++) { int x = query[i].ff; int w = query[i].ss; if(type[i] == 2) { ask.push_back(i); } else { upt.push_back(x); eraser(x); } } sort(ask.begin(), ask.end(), [&](int i, int j) { return query[i].ss > query[j].ss; }); vector<int> join[BLOCK_sz]; for(int i = L; i < R; i++) { int x = query[i].ff; int w = query[i].ss; if(type[i] == 1) { weight[i] = w; } else { for(int j : upt) if(weight[j] >= w) join[i - L].push_back(j); } } DSU azaa; set<edge>::iterator it = SET.begin(); for(int cur : ask) { // current query ID const int u = query[cur].ff; const int w = query[cur].ss; while(it != SET.end() && (*it).w >= w) { azaa.unite((*it).u, (*it).v); it++; } int snap = azaa.hist.size(); for(int j : join[cur - L]) { int u, v; tie(u, v) = edges[j]; azaa.unite(u, v); } int p = azaa.parent(u); ans[cur] = -azaa.par[p]; azaa.roll_back(snap); for(int i = 1; i <= n; i++) { int j = azaa.parent(i); } } for(int i = L; i < R; i++) { if(type[i] == 2) continue; int x = query[i].ff; int w = query[i].ss; weight[x] = w; } for(int i : upt) { int u = edges[i].ff; int v = edges[i].ss; int w = weight[i]; SET.insert(edge(i, u, v, w)); } if(SET.size() > m) for(;;); if(SET.size() < m) return 1; } for(int i = 0; i < q; i++) if(type[i] == 2) cout << ans[i] << endl; #ifdef LOCAL auto TIME_en = chrono::steady_clock::now(); int TIME = chrono::duration_cast<chrono::milliseconds> (TIME_en - TIME_st).count(); cout << "----------------------------\n"; cout << "total time: " << TIME << "ms\n"; #endif 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...