Submission #1120284

#TimeUsernameProblemLanguageResultExecution timeMemory
1120284matei__bDuathlon (APIO18_duathlon)C++17
0 / 100
252 ms42544 KiB
#include <bits/stdc++.h> #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/tree_policy.hpp> #define ll long long #define ull unsigned long long #define ld long double #define chad char #define mod 1'000'000'007 #define dim 100005 #define lim 1000000 #define BASE 31 #define NMAX 21'005 #define FOR(i,a,b) for(int i=(a); i<=(b); i++) #define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update> #define pii pair<int,int> #define pb push_back #define mp make_pair #define nr_biti __builtin_popcount using namespace __gnu_pbds; using namespace std; ifstream fin("b.in"); ofstream fout("b.out"); int t=1; int n,m; vector<int> g[dim]; vector<int> gt[dim]; int low[dim],tin[dim]; bool viz[dim]; int timer; unordered_map<int,bool> is_bridge[dim]; void dfs(int nod,int daddy=0) { viz[nod]=1; low[nod]=tin[nod]=++timer; for(auto it:g[nod]) { if(it==daddy) continue; if(viz[it]) { low[nod]=min(low[nod],tin[it]); } else { dfs(it,nod); low[nod]=min(low[nod],low[it]); if(low[it]>tin[nod]) is_bridge[nod][it]=is_bridge[it][nod]=1; } } } int comp[dim],nr; ull sz_comp[dim]; void dfs1(int nod) { viz[nod]=1; comp[nod]=nr; sz_comp[nr]++; for(auto it:g[nod]) { if(!viz[it] && !is_bridge[nod][it]) dfs1(it); } } ull ans; ull sz[dim]; void dfs2(int nod,int daddy=0) { viz[nod]=1; sz[nod]+=sz_comp[nod]; for(auto it:gt[nod]) { if(it==daddy) continue; dfs2(it,nod); sz[nod]+=sz[it]; } // nu pot sa iau un nod marginal ca start if(sz_comp[nod]>=3) { // pot sa aleg toate in aceiasi componenta ans+=(sz_comp[nod]*(sz_comp[nod]-1)*(sz_comp[nod]-2)); // acum pot sa aleg 2 din aceiasi componenta // sa zicem ca vreau sa merg in sus intai // e clar ca nu pot sa iau nodul de legatura ca start (as trece de 2 ori prin el) ull add=(sz_comp[nod]-1)*(sz_comp[nod]-1); ans+=(2*(n-sz[nod])*add); // daca merg in jos // sa zicem ca am mai multi fii f1,f2,f3,...fk // in cazul in care imi aleg un capat in unul din acesti fii e imposibil ca celalalt capat sa fie in nodul de // legatura // sa zicem ca am avea sum (sz_comp[nod]-1)*(sz_comp[nod]-1)*sz[f1] + ... // (sz_comp[nod]-1)*(sz_comp[nod]-1)*(sz[nod]-sz_comp[nod]) ans+=(2*(sz[nod]-sz_comp[nod])*add); // acum sa zicem ca aleg un singur nod din componenta mea // pot sa iau unul de sus si unul de jos // adk (sz[nod]-sz_comp[nod])*(n-sz[nod])*sz_comp[nod] // pot sa iau 2 noduri din subarbori diferiti ai fiilor // sz[f1]*(sz[nod]-sz_comp[nod]-sz[f1]) + ... ans+=(2*(n-sz[nod])*(sz_comp[nod])*(sz[nod]-sz_comp[nod])); for(auto it:gt[nod]) { if(it==daddy) continue; ans+=(sz[it]*(sz[nod]-sz_comp[nod]-sz[it])*sz_comp[nod]); } } else if(sz_comp[nod]==2) { ull add=(sz_comp[nod]-1)*(sz_comp[nod]-1); ans+=(2*(n-sz[nod])*add); ans+=(2*(sz[nod]-sz_comp[nod])*add); ans+=(2*(n-sz[nod])*(sz_comp[nod])*(sz[nod]-sz_comp[nod])); for(auto it:gt[nod]) { if(it==daddy) continue; ans+=(sz[it]*(sz[nod]-sz_comp[nod]-sz[it])*sz_comp[nod]); } } else { ans+=(2*(n-sz[nod])*(sz_comp[nod])*(sz[nod]-sz_comp[nod])); for(auto it:gt[nod]) { if(it==daddy) continue; ans+=(sz[it]*(sz[nod]-sz_comp[nod]-sz[it])*sz_comp[nod]); } } } void solve() { cin >> n >> m; for(int i=1; i<=m; i++) { int x,y; cin >> x >> y; g[x].pb(y); g[y].pb(x); } ull ans1=0; for(int i=1; i<=n; i++) { if(!viz[i]) dfs(i); } for(int i=1; i<=n; i++) viz[i]=0; for(int i=1; i<=n; i++) { if(!viz[i]) { ++nr; dfs1(i); } } for(int i=1; i<=n; i++) { for(auto it:g[i]) if(comp[i]!=comp[it]) gt[comp[i]].pb(comp[it]); } for(int i=1; i<=n; i++) viz[i]=0; for(int i=1; i<=nr; i++) { if(!viz[i]) { ans=0; dfs2(i); ans1+=ans; } } cout << ans1; } int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); //cin >> t; while(t--) solve(); 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...