Submission #1161931

#TimeUsernameProblemLanguageResultExecution timeMemory
1161931LithaniumBridges (APIO19_bridges)C++17
100 / 100
1077 ms11284 KiB
#pragma GCC optimize("Ofast,unroll-loops") #include <bits/stdc++.h> using namespace std; int dsu[50005]; int sz[50005]; int K = 400; int find(int n) { if (dsu[n] == n) return n; return dsu[n] = find(dsu[n]); } void merge(int a, int b) { a = find(a); b = find(b); if (a != b) { if (sz[a] < sz[b]) swap(a, b); dsu[b] = a; sz[a] += sz[b]; } } int dt[100005][3]; int N, M; int res[100005]; bool seen[50005]; vector<int> adj[50005]; int ans[850]; int CURR = 0; struct Query { int op, a, b; }; set<tuple<int, int, int>> edges; void dfs(int n) { CURR += sz[n]; seen[n] = 1; for (int i:adj[n]) if (!seen[i]) dfs(i); } void solve(vector<Query> &batch) { // find which edges are not impacted vector<tuple<int, int, int>> todo; vector<int> changed; for (int i = 0; i < batch.size(); i ++) { Query Q = batch[i]; if (Q.op == 1) changed.push_back(Q.a); else todo.push_back({Q.b, Q.a, i}); } sort(todo.begin(), todo.end()); for (int i:changed) { edges.erase({dt[i][0], dt[i][1], dt[i][2]}); } auto ptr = edges.begin(); for (int i = 1; i <= N; i ++) dsu[i] = i, sz[i] = 1; // Calculate edges memset(ans, 0, sizeof(ans)); for (auto [w, n, id]:todo) { // add all the edges while (ptr != edges.end()) { auto [a, b, c] = *ptr; if (a <= w) { merge(b, c); ptr ++; } else { break; } } // find the extra merges for (int i:changed) res[i] = dt[i][0]; for (int i = 0; i < id; i ++) { Query Q = batch[i]; if (Q.op == 1) { res[Q.a] = Q.b; } } for (int i:changed) { if (res[i] <= w) { // make edge int t1 = find(dt[i][1]), t2 = find(dt[i][2]); adj[t1].push_back(t2); adj[t2].push_back(t1); } res[i] = 0; } CURR = 0; dfs(find(n)); ans[id] = CURR; // clear the result seen[find(n)] = 0; for (int i:changed) { int t1 = find(dt[i][1]), t2 = find(dt[i][2]); adj[t1].clear(); adj[t2].clear(); seen[t1] = 0; seen[t2] = 0; } } for (int i:ans) if (i != 0) cout << i << "\n"; // push this batch of data over for (Query Q:batch) if (Q.op == 1) dt[Q.a][0] = Q.b; for (int i:changed) edges.insert({dt[i][0], dt[i][1], dt[i][2]}); } int main() { ios_base::sync_with_stdio(false); cin.tie(0); cin >> N >> M; if (M == 100000) K = 820; for (int i = 1; i <= M; i ++) { cin >> dt[i][1] >> dt[i][2] >> dt[i][0]; dt[i][0] = -dt[i][0]; edges.insert({dt[i][0], dt[i][1], dt[i][2]}); } vector<Query> batch; int Q; cin >> Q; auto start = clock(); int bruh = 0, tot = 0; for (int i = 1; i <= Q; i ++) { int a, b, c; cin >> a >> b >> c; if (a == 1) bruh ++; tot ++; c = -c; batch.push_back({a, b, c}); if (bruh == K or tot == 800) { solve(batch); batch.clear(); tot = 0, bruh = 0; } } if (!batch.empty()) solve(batch); }
#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...