Submission #1271339

#TimeUsernameProblemLanguageResultExecution timeMemory
1271339VMaksimoski008Making Friends on Joitter is Fun (JOI20_joitter2)C++20
0 / 100
21 ms42560 KiB
#include <bits/stdc++.h> #define ar array //#define int long long using namespace std; using ll = long long; using pii = pair<int, int>; using pll = pair<ll, ll>; const int mod = 1e9 + 7; const ll inf = 1e18; 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; 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); //samo vo starite ans -= (f(size[a]) + f(size[b])); //koga ke se spojat ans += f(size[a]+size[b]); // cout << "after p1: " << ans << endl; //directed edges for(auto u : st[a]) { if(same_set(u, a)) continue; // cout << "dir " << u << " to " << a << endl; if(!same_set(b, u)) ans += size[b]; else ans -= size[a]; } for(auto u : st[b]) { if(same_set(u, b)) continue; // cout << "dir " << u << " to " << b << endl; if(!same_set(a, u)) ans += size[a]; else ans -= size[b]; } // cout << "after p2: " << ans << endl; 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); } 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); } 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)) uni(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); } void print() { // for(int i=1; i<=n; i++) cout << par[i] << " "; // cout << endl; // cout << "print st: \n"; // for(int i=1; i<=n; i++) { // if(i != find(i)) continue; // cout << i << ": "; // for(int j : st[i]) cout << j << " "; // cout << endl; // } // cout << "print in: \n"; // for(int i=1; i<=n; i++) { // if(i != find(i)) continue; // cout << i << ": "; // for(int j : in[i]) cout << j << " "; // cout << endl; // } // cout << "print out: \n"; // for(int i=1; i<=n; i++) { // if(i != find(i)) continue; // cout << i << ": "; // for(int j : out[i]) cout << j << " "; // cout << endl; // } } }; 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); // dsu.print(); cout << dsu.ans << '\n'; } }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...