Submission #967352

#TimeUsernameProblemLanguageResultExecution timeMemory
967352steveonalexDuathlon (APIO18_duathlon)C++17
100 / 100
132 ms60772 KiB
#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef unsigned long long ull; #define ALL(v) (v).begin(), (v).end() #define MASK(i) (1LL << (i)) #define GETBIT(mask, i) (((mask) >> (i)) & 1) // mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count()); mt19937_64 rng(1); ll rngesus(ll l, ll r){return ((ull) rng()) % (r - l + 1) + l;} ll max(ll a, ll b){return (a > b) ? a : b;} ll min(ll a, ll b){return (a < b) ? a : b;} ll LASTBIT(ll mask){return mask & (-mask);} ll pop_cnt(ll mask){return __builtin_popcountll(mask);} ll ctz(ll mask){return __builtin_ctzll(mask);} ll clz(ll mask){return __builtin_clzll(mask);} ll logOf(ll mask){return 63 - clz(mask);} template <class T1, class T2> bool minimize(T1 &a, T2 b){ if (a > b){a = b; return true;} return false; } template <class T1, class T2> bool maximize(T1 &a, T2 b){ if (a < b){a = b; return true;} return false; } template <class T> void printArr(T& a, string separator = " ", string finish = "\n", ostream& out = cout){ for(auto i: a) out << i << separator; out << finish; } template <class T> void remove_dup(vector<T> &a){ sort(ALL(a)); a.resize(unique(ALL(a)) - a.begin()); } const int N = 1e5 + 69; int n, m; vector<int> graph[N], dfs_tree[N]; int num[N], low[N]; bool isJoint[N]; vector<int> st; int dfs_cnt; vector<vector<int>> bbc; void tarjan(int u, int p){ num[u] = low[u] = ++dfs_cnt; vector<int> child; for(int v: graph[u]) { if (v == p) {p = -1; continue;} if (num[v]){ minimize(low[u], num[v]); } else{ child.push_back(v); tarjan(v, u); minimize(low[u], low[v]); if (low[v] >= num[u]){ isJoint[u] = true; } } } if (u == p) isJoint[u] = isJoint[u] && (child.size() >= 2); for(int v: child){ if (isJoint[u] && low[v] >= num[u]) dfs_tree[u].push_back(-v); else dfs_tree[u].push_back(v); } } void get_block(int u){ st.push_back(u); for(int v: dfs_tree[u]){ get_block(abs(v)); if (v < 0){ bbc.push_back({}); while(bbc.back().empty() || bbc.back().back() != abs(v)){ bbc.back().push_back(st.back()); st.pop_back(); } bbc.back().push_back(u); } } } vector<int> bc_tree[2*N]; int joint_cnt = 0; int pos[2*N]; int sz[2 * N]; int generate_block_cut_tree(){ dfs_cnt = 0; for(int i= 1; i<=n; ++i) if (num[i] == 0){ tarjan(i, i); get_block(i); if (st.size()) { bbc.push_back(st); st.clear(); } } int idx = 0; for(int i= 1; i<=n; ++i){ if (!isJoint[i]) continue; joint_cnt++; pos[i] = ++idx; sz[idx] = 1; } // cerr << "\n"; for(vector<int> i: bbc){ // printArr(i); ++idx; sz[idx] = i.size(); for(int j: i){ if (isJoint[j]){ int u = idx, v = pos[j]; sz[v]--; // cerr << u << " " << v << "\n"; bc_tree[u].push_back(v); bc_tree[v].push_back(u); } } } return idx; } bool visited[N * 2]; int og[N * 2]; ll ans = 0; void get_sz(int u, int p){ visited[u] = 1; og[u] = sz[u]; for(int v: bc_tree[u]) if (v != p){ get_sz(v, u); sz[u] += sz[v]; } } void dfs(int u, int p, int source){ if (u <= joint_cnt){ vector<pair<int, int>> child; for(int v: bc_tree[u]){ if (v != p) child.push_back({sz[v] - 1, v}); else child.push_back({sz[source] - sz[u] - 1, v}); } int sum = 0; // cerr << "Ver: " << u << "\n"; for(pair<int, int> i: child) { sum += i.first; // cerr << i.first << " " << (og[i.second]-1) << "\n"; } // cerr << "Sum: " << sum << "\n"; // cerr << "\n"; for(pair<int, int> i: child){ ans -= 1LL * (og[i.second] - 1) * (sum - i.first) * (sum - i.first - 1); ans -= 2LL * (og[i.second] - 1) * (sum - i.first); } } for(int v: bc_tree[u]) if (v != p){ dfs(v, u, source); } } int main(void){ ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin >> n >> m; // if (m != n - 1) return -1; for(int i= 0; i<m; ++i){ int u, v; cin >> u >> v; graph[u].push_back(v); graph[v].push_back(u); } int tree_sz = generate_block_cut_tree(); for(int i= joint_cnt + 1; i<=tree_sz; ++i) if (!visited[i]){ get_sz(i, i); int M = sz[i]; ans += 1LL * M * (M - 1) * (M - 2); dfs(i, i, 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...