제출 #231295

#제출 시각아이디문제언어결과실행 시간메모리
231295WLZ조이터에서 친구를 만드는건 재밌어 (JOI20_joitter2)C++14
100 / 100
1314 ms72140 KiB
#include "bits/stdc++.h" using namespace std; int n, m; long long ans = 0; vector<int> p, sz; vector< set<int> > in_v, in_group, out_group, members; vector<long long> cost; int root(int x) { if (p[x] == x) { return x; } return (p[x] = root(p[x])); } void merge(int u, int v) { u = root(u); v = root(v); if (u == v) { return; } ans -= (long long) members[u].size() * (long long) (members[u].size() + in_v[u].size() - 1); ans -= (long long) members[v].size() * (long long) (members[v].size() + in_v[v].size() - 1); if (members[u].size() + in_v[u].size() + in_group[u].size() + out_group[v].size() < members[v].size() + in_v[v].size() + in_group[v].size() + out_group[v].size()) { swap(u, v); } for (auto& x : members[v]) { members[u].insert(x); if (in_v[u].count(x)) { in_v[u].erase(x); } } members[v].clear(); for (auto& x : in_v[v]) { if (!members[u].count(x)) { in_v[u].insert(x); } } in_v[v].clear(); ans += (long long) members[u].size() * (long long) (members[u].size() + in_v[u].size() - 1); vector<int> to_merge; for (auto& x : in_group[v]) { if (out_group[u].count(x)) { to_merge.push_back(x); } out_group[x].erase(v); out_group[x].insert(u); in_group[u].insert(x); } in_group[v].clear(); for (auto& x : out_group[v]) { if (in_group[u].count(x)) { to_merge.push_back(x); } in_group[x].erase(v); in_group[x].insert(u); out_group[u].insert(x); } out_group[v].clear(); in_group[u].erase(v); out_group[u].erase(v); p[v] = u; for (auto& x : to_merge) { merge(u, x); } } void add_edge(int u, int v) { v = root(v); if (v == root(u)) { return; } if (!in_v[v].count(u)) { ans += (long long) members[v].size(); in_v[v].insert(u); } u = root(u); in_group[v].insert(u); out_group[u].insert(v); if (in_group[u].count(v)) { merge(u, v); } } int main() { ios::sync_with_stdio(false); cin.tie(0); cin >> n >> m; p.resize(n + 1); iota(p.begin(), p.end(), 0); in_v.resize(n + 1); in_group.resize(n + 1); out_group.resize(n + 1); members.resize(n + 1); for (int i = 1; i <= n; i++) { members[i].insert(i); } for (int i = 0; i < m; i++) { int u, v; cin >> u >> v; add_edge(u, v); cout << ans << '\n'; } return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...