# | Time | Username | Problem | Language | Result | Execution time | Memory |
---|---|---|---|---|---|---|---|
981972 | kh0i | Making Friends on Joitter is Fun (JOI20_joitter2) | C++17 | 902 ms | 69116 KiB |
This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include "bits/stdc++.h"
using namespace std;
#ifdef LOCAL
#include "debug.h"
#else
#define debug(...)
#endif
using ll = long long;
using pii = pair<int, int>;
#define F first
#define S second
#define sz(x) (int)((x).size())
#define all(x) (x).begin(), (x).end()
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll get_rand(ll l, ll r) {
assert(l <= r);
return uniform_int_distribution<ll> (l, r)(rng);
}
const int N = 1e5 + 3;
int n, m;
int p[N];
ll sz[N];
set<int> fl[N], rfl[N], comp[N];
queue<pii> to_merge;
ll ans;
int find(int x) { return x == p[x] ? x : p[x] = find(p[x]); }
void insert_weak(int u, int v){
fl[u].insert(v);
rfl[v].insert(u);
if(fl[v].count(u))
to_merge.push({u, v});
}
int dsu_sz(int u) { return sz(comp[u]) + sz(fl[u]) + sz(rfl[u]); }
void merge_set(int u, int v){
u = find(u), v = find(v);
if(u == v) return;
if(dsu_sz(u) < dsu_sz(v)) swap(u, v);
ans += (sz[v] * sz(comp[u])) + (sz[u] * sz(comp[v]));
p[v] = u;
sz[u] += sz[v];
for(int i : comp[v]){
if(comp[u].count(i)) ans -= sz[u];
else comp[u].insert(i);
}
fl[u].erase(v); rfl[v].erase(u);
fl[v].erase(u); rfl[u].erase(v);
for(int i : fl[v]){
rfl[i].erase(v);
insert_weak(u, i);
}
for(int i : rfl[v]){
fl[i].erase(v);
insert_weak(i, u);
}
}
void solve(){
cin >> n >> m;
for(int i = 1; i <= n; ++i){
sz[i] = 1, p[i] = i;
comp[i].insert(i);
}
while(m--){
int u, v;
cin >> u >> v;
v = find(v);
if(find(u) != v and !comp[v].count(u)){
comp[v].insert(u);
ans += sz[v];
u = find(u);
insert_weak(u, v);
while(!to_merge.empty()){
merge_set(to_merge.front().F, to_merge.front().S);
to_merge.pop();
}
}
cout << ans << '\n';
}
}
int32_t main() {
cin.tie(nullptr)->sync_with_stdio(0);
#define task "troll"
if(fopen(task".inp", "r")){
freopen(task".inp", "r", stdin);
freopen(task".out", "w", stdout);
}
int test = 1;
// cin >> test;
for(int i = 1; i <= test; ++i){
// cout << "Case #" << i << ": ";
solve();
}
#ifdef LOCAL
cerr << "\n[Time]: " << 1000.0 * clock() / CLOCKS_PER_SEC << " ms.\n";
#endif
return 0;
}
Compilation message (stderr)
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |