Submission #565282

#TimeUsernameProblemLanguageResultExecution timeMemory
565282Drew_Duathlon (APIO18_duathlon)C++17
31 / 100
129 ms32012 KiB
#include <bits/stdc++.h> using namespace std; #define pb push_back #define mp make_pair #define ll long long #define ii pair<int, int> #define f1 first #define s2 second const int MAX = 1e5 + 7; static ll ans = 0; int N, M; bitset<MAX> arti; vector<ii> edge; //[index]: {from, to} vector<int> adj[MAX]; //[from]: to // bct int compsz; int id[MAX], sz[2*MAX]; vector<int> tree[2*MAX]; // solve bitset<2 * MAX> vst; int child_sz[2 * MAX], parent[2 * MAX]; vector<int> nodes; void build_bct() { int disc[MAX], low[MAX]; vector<vector<int>> comps; int ctr = 1; vector<int> sk; const auto getArti = [&](const auto &self, int node, int par) -> void { disc[node] = low[node] = ctr++; sk.pb(node); for (int to : adj[node]) if (to != par) { if (disc[to] == -1) { self(self, to, node); low[node] = min(low[node], low[to]); if (low[to] >= disc[node]) { arti[node] = (par != -1 || disc[to] > 1 + disc[node]); comps.pb({node}); for (; comps.back().back() != to; sk.pop_back()) comps.back().pb(sk.back()); } } else low[node] = min(low[node], disc[to]); } }; memset(disc, -1, sizeof(disc)); memset(low, -1, sizeof(low)); comps.clear(); ctr = 1; for (int i = 1; i <= N; ++i) if (disc[i] == -1) getArti(getArti, i, -1); // build tree ctr = 1; for (int i = 1; i <= N; ++i) if (arti[i]) sz[ctr] = 1, id[i] = ctr++; for (auto &comp : comps) { sz[ctr] = (int)comp.size(); for (int node : comp) { if (!arti[node]) id[node] = ctr; else { sz[ctr]--; tree[ctr].pb(id[node]); tree[id[node]].pb(ctr); // cerr << ctr << " - " << id[node] << '\n'; } } ctr++; } compsz = ctr - 1; // s and f from other two same group; c from the same ctr = 1; for (int i = 1; i <= N; ++i) if (arti[i]) { for (int to : tree[ctr]) ans += 1ll * sz[to] * (sz[to] - 1); ctr++; } } int dfs(int node) { vst[node] = true; child_sz[node] = sz[node]; nodes.pb(node); for (int to : tree[node]) if (to != parent[node]) parent[to] = node, child_sz[node] += dfs(to); return child_sz[node]; } void solve(int root) { nodes.clear(); parent[root] = -1; int all = dfs(root); for (int node : nodes) { //s, c, f from the same cycle ans += 1LL * sz[node] * (sz[node] - 1) * (sz[node] - 2); //s from other; c,f from the same //f from other; s,c from the same for (int to : tree[node]) { int tmp = child_sz[to]; if (child_sz[node] < child_sz[to]) //to is the parent tmp = child_sz[root] - child_sz[node]; ans += 2ll * tmp * sz[node] * (sz[node] - 1); } //s and f from other two different group; c from the same for (int to : tree[node]) { int tmp = child_sz[to]; if (parent[node] == to) tmp = child_sz[root] - child_sz[node]; // cerr << to << " " << tmp << '\n'; ans += 1ll * tmp * sz[node] * (all - tmp - sz[node]); } } } int32_t main() { ios :: sync_with_stdio(0); cin.tie(0); cout.tie(0); cin >> N >> M; edge.resize(M); for (auto &[u, v] : edge) { cin >> u >> v; adj[u].pb(v); adj[v].pb(u); } build_bct(); for (int i = 1; i <= compsz; ++i) if (!vst[i]) solve(i); cout << ans << '\n'; return 0; }
#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...