Submission #229719

#TimeUsernameProblemLanguageResultExecution timeMemory
229719lycDuathlon (APIO18_duathlon)C++14
49 / 100
108 ms37108 KiB
#include <bits/stdc++.h> using namespace std; #define TRACE(x) cerr << #x << " :: " << x << endl #define _ << " " << #define SZ(x) (int)(x).size() #define ALL(x) (x).begin(),(x).end() #define FOR(i,a,b) for(int i=(a);i<=(b);++i) #define RFOR(i,a,b) for (int i=(a);i>=(b);--i) const int MX_N = 1e5+5; int N, M; vector<int> al[MX_N]; namespace BCT { int pre[MX_N], low[MX_N], cnt, root, rootChildren; vector<int> stk; int comp[MX_N], sz[MX_N]; int nap, nv; vector<int> tree[MX_N]; void dfs(int u, int p) { pre[u] = low[u] = ++cnt; for (int v : al[u]) if (v != p) { if (pre[v] == -1) { dfs(v,u); if (u == root) ++rootChildren; else if (comp[u] == -1 && low[v] >= pre[u]) comp[u] = ++nv, sz[nv] = 1; low[u] = min(low[u],low[v]); } else { low[u] = min(low[u],pre[v]); } } } void addEdge(int u, int v) { tree[u].push_back(v); tree[v].push_back(u); } void decomp(int u, int p) { pre[u] = ++cnt; stk.push_back(u); for (int v : al[u]) if (v != p) { if (pre[v] == -1) { int st = stk.back(); decomp(v,u); if (comp[u] != -1 && low[v] >= pre[u]) { sz[++nv] = 1; addEdge(comp[u],nv); while (stk.back() != st) { int& w = stk.back(); stk.pop_back(); ++sz[nv]; if (comp[w] == -1) comp[w] = nv; else addEdge(comp[w],nv); } } } } } void run() { fill_n(comp,N+1,-1); nv = 0; fill_n(pre,N+1,-1); cnt = 0; FOR(u,1,N) if (pre[u] == -1) { root = u, rootChildren = 0; dfs(u,0); if (rootChildren > 1) comp[u] = ++nv, sz[nv] = 1; } nap = nv; fill_n(pre,N+1,-1); cnt = 0; FOR(u,1,N) if (pre[u] == -1) { stk.clear(); decomp(u,0); if (comp[u] == -1) { sz[++nv] = 0; while (!stk.empty()) { int& w = stk.back(); stk.pop_back(); ++sz[nv]; if (comp[w] == -1) comp[w] = nv; else addEdge(comp[w],nv); } } } } void dbg() { FOR(i,1,N){ TRACE(i _ pre[i] _ low[i] _ comp[i]); } TRACE(nv); cout << "APs: "; FOR(i,1,N){ if (comp[i] <= nap) cout << i << ' '; } cout << endl; FOR(i,1,nv){ cout << i << " (" << sz[i] << "): "; for(int v : tree[i]) { cout << v << ' '; } cout << endl; } } long long ans; int sub[MX_N]; void precomp(int u, int p) { sub[u] = sz[u]; for (int v : tree[u]) if (v != p) { precomp(v,u); sub[u] += sub[v]; --sub[u]; } //TRACE(u _ sz[u] _ u _ sub[u]); } void trav(int u, int p, int all) { //TRACE("trav" _ u _ p _ all); if (u <= nap) { int other = all - 1; for (int v : tree[u]) { int cur; if (v == p) { cur = all-sub[u]; } else { cur = sub[v]-1; trav(v,u,all); } //long long two = 1LL * cur * (other-cur); //long long one = 1LL * (sz[v]-1) * (sz[v]-2); //long long snk = 2LL * (cur+1-sz[v]) * (sz[v]-2); //TRACE(u _ v _ "add" _ cur _ (other-cur) _ "res" _ two _ one _ snk); ans += 1LL * cur * (other-cur); // ep in diff ans += 1LL * (sz[v]-1) * (sz[v]-2); // ep in same ans += 2LL * (cur+1-sz[v]) * (sz[v]-2); // ep in same subtree } } else { int inside = (sz[u] - SZ(tree[u])); int other = all - inside; for (int v : tree[u]) { other -= sz[v]; } for (int v : tree[u]) { int cur; if (v == p) { cur = all-sub[u]-(sz[p]-1); } else { cur = sub[v]-sz[v]; trav(v,u,all); } //long long two = inside * cur * (other-cur); //long long one = 2LL * inside * cur * (sz[u]-2); //long long snk = 1LL * (SZ(tree[u])-2) * cur * (other-cur); //TRACE(u _ v _ "add" _ cur _ (other-cur) _ "res" _ two _ one _ snk); ans += 1LL * inside * cur * (other-cur);// both ep outside ans += 2LL * inside * cur * (sz[u]-2); // one ep outside ans += 1LL * (SZ(tree[u])-2) * cur * (other-cur); // both ep outside, mid is ap } //long long zero = 1LL * inside * (sz[u]-1) * (sz[u]-2); //TRACE(u _ zero); if (sz[u] >= 3) ans += 1LL * inside * (sz[u]-1) * (sz[u]-2); } } long long solve() { ans = 0; fill_n(sub,N+1,-1); FOR(i,1,nv) if (sub[i] == -1) { precomp(i,0); trav(i,0,sub[i]); } return ans; } }; int main() { ios::sync_with_stdio(false); cin.tie(0); cin >> N >> M; FOR(i,1,M){ int U, V; cin >> U >> V; al[U].push_back(V); al[V].push_back(U); } BCT::run(); //BCT::dbg(); cout << BCT::solve() << '\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...