Submission #1124538

#TimeUsernameProblemLanguageResultExecution timeMemory
1124538Whisper조이터에서 친구를 만드는건 재밌어 (JOI20_joitter2)C++20
100 / 100
801 ms66140 KiB
#include <bits/stdc++.h> using namespace std; using ll = long long; #define int long long #define FOR(i, a, b) for (int i = (a); i <= (b); i++) #define FORD(i, a, b) for (int i = (b); i >= (a); i --) #define REP(i, a) for (int i = 0; i < (a); ++i) #define REPD(i, a) for (int i = (a) - 1; i >= 0; --i) #define MASK(i) (1LL << (i)) #define BIT(x, i) (((x) >> (i)) & 1) constexpr ll LINF = (1ll << 60); constexpr int INF = (1ll << 30); constexpr int Mod = 1e9 + 7; mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); /* Phu Trong from Nguyen Tat Thanh High School for gifted student */ template <class X, class Y> bool minimize(X &x, const Y &y){ X eps = 1e-9; if (x > y + eps) {x = y; return 1;} return 0; } template <class X, class Y> bool maximize(X &x, const Y &y){ X eps = 1e-9; if (x + eps < y) {x = y; return 1;} return 0; } #define MAX 100005 //M log (M)^2 int pa[MAX], siz[MAX]; int ans = 0; int numNode, numEdge; int fp(int u){ return pa[u] == u ? u : pa[u] = fp(pa[u]); } set<int> adj[MAX], radj[MAX], child[MAX]; queue<pair<int, int>> todo; void add_weak_edge(int u, int v){ adj[u].insert(v); radj[v].insert(u); if(adj[v].count(u)){ //a strong edge appears todo.emplace(u, v); } } int getSize(int u){ return (int)adj[u].size() + (int)radj[u].size() + (int)child[u].size(); } void joint(int u, int v){ u = fp(u), v = fp(v); if(u == v) return; if(getSize(u) < getSize(v)) swap(u, v); ans += 1LL * siz[u] * (int)child[v].size() + 1LL * siz[v] * (int)child[u].size(); pa[v] = u; siz[u] += siz[v]; for (auto&s : child[v]){ if(child[u].count(s)) ans -= siz[u]; else child[u].insert(s); } adj[u].erase(v); radj[u].erase(v); adj[v].erase(u); radj[v].erase(u); for (int i : adj[v]){ radj[i].erase(v); add_weak_edge(u, i); } for (int i : radj[v]){ adj[i].erase(v); add_weak_edge(i, u); } } void process(void){ cin >> numNode >> numEdge; for (int i = 1; i <= numNode; ++i){ siz[i] = 1; child[i].insert(i); pa[i] = i; } for (int i = 1; i <= numEdge; ++i){ int u, v; cin >> u >> v; v = fp(v); if(!child[v].count(u) and fp(u) != v){ child[v].insert(u); //u is v's child if u is following v ans += siz[v]; u = fp(u); add_weak_edge(u, v); while(todo.size()){ int u, v; tie(u, v) = todo.front(); todo.pop(); joint(u, v); } } cout << ans << '\n'; } } signed main(){ #define name "Whisper" cin.tie(nullptr) -> sync_with_stdio(false); // freopen(name".inp", "r", stdin); // freopen(name".out", "w", stdout); process(); return (0 ^ 0); }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...