Submission #384084

#TimeUsernameProblemLanguageResultExecution timeMemory
384084VodkaInTheJarMaking Friends on Joitter is Fun (JOI20_joitter2)C++14
17 / 100
5046 ms63724 KiB
#include <bits/stdc++.h> #pragma GCC optimize("O3") #define endl '\n' using namespace std; const int maxn = 1e5 + 3; int n, m; void read() { cin >> n >> m; } int par[maxn], sz[maxn]; set <int> adj[maxn], rev_adj[maxn], members[maxn]; int find_root(int ver) { if (ver == par[ver]) return ver; return par[ver] = find_root(par[ver]); } long long ans = 0; void merge(int a, int b) { a = find_root(a), b = find_root(b); if (a == b) return; ans -= 1ll * sz[a] * (sz[a] - 1); ans -= 1ll * sz[b] * (sz[b] - 1); ans -= 1ll * (int)rev_adj[a].size() * sz[a]; ans -= 1ll * (int)rev_adj[b].size() * sz[b]; if (sz[a] < sz[b]) swap(a, b); for (auto i: members[b]) members[a].insert(i); for (auto j: adj[b]) if (j != a) adj[a].insert(j); for (auto j: rev_adj[b]) { if (find_root(j) == a) continue; adj[find_root(j)].erase(b); adj[find_root(j)].insert(a); rev_adj[a].insert(j); } adj[a].erase(b); vector <int> to_remove; for (auto i: members[b]) if (rev_adj[a].find(i) != rev_adj[a].end()) to_remove.push_back(i); for (auto i: to_remove) rev_adj[a].erase(i); /* cout << a << ":"; for (auto i: adj[a]) cout << i << " "; cout << endl; cout << endl; for (auto i: rev_adj[a]) cout << i << " "; // cout << endl; // cout << rev_adj[1].size() << endl; // cout << endl; exit(0); */ par[b] = a; sz[a] += sz[b]; ans += 1ll * sz[a] * (sz[a] - 1); ans += 1ll * (int)rev_adj[a].size() * sz[a]; } pair <int, int> e[maxn * 3]; void solve() { for (int i = 1; i <= n; i++) { par[i] = i, sz[i] = 1; members[i].insert(i); } for (int i = 1; i <= m; i++) { cin >> e[i].first >> e[i].second; int a = find_root(e[i].first), b = find_root(e[i].second); if (a != b) { ans -= 1ll * (int)rev_adj[b].size() * sz[b]; adj[a].insert(b); rev_adj[b].insert(e[i].first); ans += 1ll * (int)rev_adj[b].size() * sz[b]; int curr = a; for (;;) { bool can = false; for (auto j: adj[curr]) if (adj[j].find(curr) != adj[j].end()) { merge(j, curr); curr = find_root(curr); can = true; break; } if (!can) break; } } //cout << i << "shit" << (int)rev_adj[2].size() << endl; // cout << find_ans(i) << endl; cout << ans << endl; } } int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); read(); solve(); }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...