제출 #956790

#제출 시각아이디문제언어결과실행 시간메모리
956790Sharky조이터에서 친구를 만드는건 재밌어 (JOI20_joitter2)C++17
100 / 100
1505 ms87348 KiB
#include <bits/stdc++.h> using namespace std; #define int long long #define siz(x) (int)x.size() const int N = 100005; int p[N], sz[N], ans = 0; map<pair<int, int>, int> mp; set<int> st[N], g1[N], g2[N]; queue<pair<int, int>> q; int find(int u) { return p[u] == u ? u : p[u] = find(p[u]); } void uni(int u, int v) { if (u == v) return; mp[{u, v}]++; g1[u].insert(v); g2[v].insert(u); if (g1[v].count(u)) q.push({u, v}); } void merge(int u, int v) { u = find(u), v = find(v); if (u == v) return; if (siz(g1[u]) + siz(g2[u]) + siz(st[u]) < siz(g1[v]) + siz(g2[v]) + siz(st[v])) swap(u, v); ans += sz[u] * siz(st[v]) + sz[v] * siz(st[u]); p[v] = u; sz[u] += sz[v]; for (int i : g1[v]) { g2[i].erase(v); uni(u, i); } g1[v].clear(); for (int i : g2[v]) { g1[i].erase(v); uni(i, u); } g2[v].clear(); for (int i : st[v]) { if (st[u].count(i)) ans -= sz[u]; else st[u].insert(i); } st[v].clear(); } int32_t main() { ios::sync_with_stdio(0); cin.tie(0); int n, m; cin >> n >> m; for (int i = 1; i <= n; i++) { p[i] = i, sz[i] = 1; st[i].insert(i); } while (m--) { int u, v; cin >> u >> v; if (st[find(v)].count(u)) { // need to delete? cout << ans << '\n'; continue; } if (find(u) == find(v)) { cout << ans << '\n'; continue; } st[find(v)].insert(u); u = find(u), v = find(v); ans += sz[v]; uni(u, v); while (!q.empty()) { auto [x, y] = q.front(); q.pop(); merge(x, y); } cout << ans << '\n'; } }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...