Submission #1271346

#TimeUsernameProblemLanguageResultExecution timeMemory
1271346VMaksimoski008Making Friends on Joitter is Fun (JOI20_joitter2)C++20
17 / 100
5095 ms87664 KiB
#include <bits/stdc++.h> using namespace std; using ll = long long; using pii = pair<int, int>; const int N = 3e5 + 5; set<int> st[N], in[N], out[N]; inline ll f(ll x) { return x * (x - 1); } struct union_find { int n; vector<int> par, size, to_rem; vector<pii> ord; ll ans = 0; union_find(int _n) : n(_n), par(n+1), size(n+1, 1) { for(int i=1; i<=n; i++) par[i] = i; } int find(int u) { if(u == par[u]) return u; return par[u] = find(par[u]); } void uni(int a, int b) { a = find(a); b = find(b); if(a == b) return ; if(size[a] < size[b]) swap(a, b); ans -= (f(size[a]) + f(size[b])); ans += f(size[a]+size[b]); for(auto u : st[a]) { if(same_set(u, a)) continue; if(!st[b].count(u)) { if(!same_set(b, u)) ans += size[b]; else ans -= size[a]; } } for(auto u : st[b]) { if(same_set(u, b)) continue; if(!st[a].count(u)) { if(!same_set(a, u)) ans += size[a]; else ans -= size[b]; } } if(out[a].count(b)) out[a].erase(b); if(out[b].count(a)) out[b].erase(a); if(in[a].count(b)) in[a].erase(b); if(in[b].count(a)) in[b].erase(a); for(int u : out[b]) { in[u].erase(b); add_edge_g(a, u); } for(int u : in[b]) { out[u].erase(b); add_edge_g(u, a); } for(int u : st[b]) { if(!same_set(u, a)) st[a].insert(u); } for(int u : st[a]) if(same_set(u, b)) to_rem.push_back(u); for(int u : to_rem) st[a].erase(u); to_rem.shrink_to_fit(); to_rem.clear(); par[b] = a; size[a] += size[b]; } void check(int a, int b) { if(same_set(a, b)) return ; if(in_comp(b, a)) return ; ans += get_size(b); add_edge_st(b, a); add_edge_g(a, b); while(!ord.empty()) { auto [u, v] = ord.back(); ord.pop_back(); uni(u, v); } } void add_edge_g(int a, int b) { a = find(a); b = find(b); out[a].insert(b); in[b].insert(a); if(out[a].count(b) && out[b].count(a)) { ord.push_back({ a, b }); } } void add_edge_st(int a, int b) { st[find(a)].insert(b); } bool in_comp(int a, int b) { return st[find(a)].count(b); } int get_size(int a) { return size[find(a)]; } bool same_set(int a, int b) { return find(a) == find(b); } }; signed main() { ios_base::sync_with_stdio(false); cout.tie(0); cin.tie(0); int n, m; cin >> n >> m; union_find dsu(n); while(m--) { int a, b; cin >> a >> b; dsu.check(a, b); cout << dsu.ans << '\n'; } }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...