Submission #548957

#TimeUsernameProblemLanguageResultExecution timeMemory
548957leakedDuathlon (APIO18_duathlon)C++17
0 / 100
117 ms23464 KiB
#include <bits/stdc++.h>

#define f first
#define s second
#define m_p make_pair
#define vec vector
#define pb push_back
#define all(x) (x).begin(),(x).end()
#define rall(x) (x).rbegin(),(x).rend()
#define sz(x) (int)(x).size()
#define pw(x) (1LL<<(x))
#define fast_prep ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
typedef long double ld;
typedef pair<ll,ll> pll;
typedef unsigned long long ull;
//#define int long long
template<class T> bool umin(T &a,const T &b){return (a>b?a=b,1:0);}
template<class T> bool umax(T &a,const T &b){return (a<b?a=b,1:0);}
const int N=1e5+1;
vec<int> g[N];
int in[N],fup[N],tt=1,mt[N],bads[N];
int sub[N];
int n;
vec<int> gr[N];
void dfs1(int v,int p){
    in[v]=fup[v]=mt[v]=tt++;
    ++n;
//    cout<<"HERET "<<v<<' '<<in[v]<<endl;
    for(auto &z : g[v]){
        if(z==p) continue;
//        cout<<"DFS "<<v<<' '<<z<<endl;
        if(in[z]){
            umin(fup[v],in[z]);
        }
        else{
            gr[v].pb(z);gr[z].pb(v);
            dfs1(z,v);
            umin(fup[v],fup[z]);
            if(fup[z]<in[v]) umax(mt[v],mt[z]);
        }
    }
}
int dp[N];
ll cnt[N];
vec<int> vc;
void dfs2(int v,int p){
    dp[v]=1;
    int total=1;
//    vc.pb(v);
    for(auto &z : gr[v]){
        if(z==p) continue;
        dfs2(z,v);
        while(sz(vc) && fup[vc.back()]>=in[v]){
            cnt[v]+=total;
            total++;
            vc.pop_back();
            ///what means bads?
        }
        dp[v]+=dp[z];
        cnt[v]+=cnt[z]+bads[z];
    }
    vc.pb(v);
}
ll bad=0;
void dfs3(int v,ll up,int p){
    ///WARNING : in cnt i consider f=v
    bad+=up;
    int du=n-dp[v];
    ll broke=up;
    int cur=(mt[v]==in[v]?du:0);
    for(auto &z : gr[v]){
        if(z==p) continue;
        if(fup[z]>=in[v]){
            broke+=1ll*cur*dp[z];
            cur+=dp[z];
        }
        broke+=cnt[z]+bads[z];
    }
    bad+=broke;

//    cout<<"BAD "<<v<<' '<<2*broke<<endl;

    du=n-dp[v]+1;
    /// now i need to upd up for whom im articular point except z
    cur=(mt[v]==in[v]?du:1);
    for(auto &z : gr[v]){
        if(z==p) continue;
        if(fup[z]>=in[v]){
            up+=1ll*cur*dp[z];
            cur+=dp[z];
        }
        up+=cnt[z];
    }
    for(auto &z : gr[v]){
        if(z==p) continue;
        ll nup=up-cnt[z];
        if(fup[z]>=in[v]){
            nup-=1ll*(dp[z]*(cur-dp[z]));
        }
        dfs3(z,nup,v);
    }
}
signed main(){
    fast_prep;
    int n,m;
    cin>>n>>m;
    for(int i=0;i<m;i++){
        int v,u;
        cin>>v>>u;
        g[v].pb(u);g[u].pb(v);
    }
//    for(int i=1;i<=n;i++) dp[i][0]=1;
    ll total=0;

    for(int i=1;i<=n;i++){
        if(!in[i]){
            ::n=0;
            vc.clear();
            dfs1(i,i);
            dfs2(i,i);
            dfs3(i,0,i);
//            cout<<::n<<endl;
            total+=1ll*::n*(::n-1)*(::n-2)-2ll*bad;
            bad=0;
        }
    }
    cout<<total;
    return 0;
}
/*
abbaaa
cbbbbccbbccbbbbbbc
(((((((()))())))))
5 5
4 2
2 5
4 1
2 1
4 5

*/
#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...