This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#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 time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |