제출 #1160972

#제출 시각아이디문제언어결과실행 시간메모리
1160972crafticat철인 이종 경기 (APIO18_duathlon)C++20
0 / 100
46 ms25240 KiB
#include <bits/stdc++.h> using namespace std; #define F0R(i, n) for (int i = 0; i < n; i++) #define FOR(i, a, b) for (int i = (a); i < (b); i++) #define ROF(i, a, b) for (int i = (a); i >= (b); i--) #define REP(i, n) for (int i = (n); i >= 0; i--) template<typename T> using V = vector<T>; using vi = vector<int>; using ll = long long; struct DSU { vi p; vi siz; int comp; DSU(int n) { p.resize(n, -1); siz.resize(n, 1); comp = n - 1; } int get(int x) { if (p[x] == -1) return x; return p[x] = get(p[x]); } void unite(int x, int y) { x = get(x); y = get(y); if (x == y) return; siz[x] += siz[y]; p[y] = x; comp--; } }; V<vi> g; vi vis; vi crits; vi minH, dep; void findCrits(int x, int p,bool root = true, int d = 0) { dep[x] = d; vis[x] = 1; int child = 0; for (auto y : g[x]) { if (vis[y] == 2) continue; if (vis[y] == 1) { if (y == p) continue; minH[x] = min(minH[x], dep[y]); continue; } findCrits(y, x, false, d + 1); child++; minH[x] = min(minH[x], minH[y]); } if (root and child > 1) crits.push_back(minH[x]); if (!root and minH[x] >= dep[x] and child > 0) crits.push_back(x); vis[x] = 2; } DSU *dsu; void dfs(int x) { vis[x] = 1; for (auto y : g[x]) { if (vis[y]) continue; dfs(y); dsu->unite(x, y); } } ll computeSiz(int x, const V<vi> &tree, const vi &siz) { ll ans = siz[x]; vis[x] = 1; for (auto y : tree[x]) { if (vis[y] == 1) continue; ans += computeSiz(y, tree, siz); } return ans; } ll solveTree(int x, int p, const V<vi> &tree, const vi &siz, vi &prefixSiz, int globalSum) { ll ans = 0; vis[x] = 2; prefixSiz[x] = siz[x]; vi sizes; for (auto y : tree[x]) { if (vis[y] == 2) continue; ans += solveTree(y, x, tree, siz, prefixSiz, globalSum); sizes.push_back(prefixSiz[y]); prefixSiz[x] += prefixSiz[y]; if (siz[y] > 1) ans += siz[y] * (siz[y] - 1) + siz[y] * (prefixSiz[y] - siz[y]); } sizes.emplace_back(globalSum - prefixSiz[x]); F0R(i, sizes.size()) { FOR(j,i + 1,sizes.size()) { ans += sizes[i] * sizes[j] * 2 * siz[x]; } } if (siz[x] > 2) ans += max(siz[x] * (siz[x] - 1) * (siz[x] -2), 0); if (siz[x] >1 ) ans += max(siz[x] * (siz[x] - 1), 0) * (globalSum - siz[x]) * 2; return ans; } int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); int n, m; cin >> n >> m; g.resize(n + 1); vis.resize(n + 1); dep.resize(n + 1); minH.resize(n + 1, 1e9); F0R(i, m) { int a, b; cin >> a >> b; g[a].push_back(b); g[b].push_back(a); } FOR(i, 1, n + 1) { if (vis[i] == 0) findCrits(i, -1); } vis.assign(n + 1, 0); for (auto c : crits) vis[c] = 1; dsu = new DSU(n + 1); FOR(i, 1, n + 1) { if (vis[i]) continue; dfs(i); } V<vi> tree(dsu->comp); vi mapTo(n + 1, -1); vi siz(dsu->comp); int nextId = 0; for (auto c : crits) { for (auto y : g[c]) { y = dsu->get(y); c = dsu->get(c); if (mapTo[y] == -1) mapTo[y] = nextId++; if (mapTo[c] == -1) mapTo[c] = nextId++; siz[mapTo[y]] = dsu->siz[y]; siz[mapTo[c]] = dsu->siz[c]; tree[mapTo[y]].push_back(mapTo[c]); tree[mapTo[c]].push_back(mapTo[y]); } } ll ans = 0; vis.assign(dsu->comp, 0); vi prefixSum(dsu->comp, 0); F0R(i, dsu->comp) { if (vis[i] == 0) { int globalSum = computeSiz(i, tree, siz); ans += solveTree(i, -1, tree, siz, prefixSum, globalSum); } } cout << n * (n - 1) * (n - 2) / 3 << '\n'; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...