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>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
#define ll long long
#define pb push_back
#define endl '\n'
#define pii pair<ll,ll>
#define F first
#define S second
#define double long double
#define all(x) (x).begin(),(x).end()
using namespace std;
using namespace __gnu_pbds;
typedef tree<ll , null_type , less_equal<ll> ,rb_tree_tag ,tree_order_statistics_node_update >ordered_set;
const int MOD = 1e9 + 7 ;
const int N= 5e5 + 10;
const ll INF= 1e18+10;
struct trp{ll F,S,T;};
ll po(ll x,ll y)
{
ll ans = 1;
while(y){
if( y & 1 ) ans *=x;
y /= 2;
x *=x;
//ans %= MOD;
//x %= MOD;
}
return ans;
}
ll ans;
ll sz[N];
ll val[N];
ll ctr = 1;
ll node[N];
bool vis[N];
ll n , m, nn ;
vector<ll>v[N];
map<pii,bool>mp;
vector<ll>com[N];
ll tin[N],low[N];
vector<ll>tree1[N];
vector<ll>no_name[N];
void dfs_br(ll x,ll p)
{
tin[x] = low[x] = ctr ++;
for(auto i : v[x]){
if(i == p) continue;
if(!tin[i]){
dfs_br(i,x);
low[x] = min(low[x], low[i]);
if(low[i] > tin[x]){
mp[{x,i}] = 1;
mp[{i,x}] = 1;
}
}
else low[x] = min(low[x] , tin[i]);
}
}
void dfs(ll x)
{
com[ctr].pb(x);
node[x] = ctr;
val[ctr] ++;
for(auto i : v[x]){
if(mp[{x,i}]){
if(node[i]){
no_name[i].pb(node[x]);
no_name[x].pb(node[i]);
tree1[node[x]].pb(node[i]);
tree1[node[i]].pb(node[x]);
}
}
else{
if(!node[i]) dfs(i);
}
}
}
void dfs_tr(ll x)
{
vis[x] = 1;
for(auto i : tree1[x]){
if(!vis[i]){
dfs_tr(i);
sz[x] += sz[i];
}
}
sz[x] += val[x];
}
void dfs_get(ll x)
{
vis[x] = 1;
if(val[x] >= 3) ans += val[x] * (val[x]-1) * (val[x]-2);
ll curr = 0;
ll h = (val[x] >= 2 ? (val[x]-1)*(val[x]-1) : 0);
vector<ll>g;
for(auto i : com[x]){
ll sm = 0;
for(auto j : no_name[i]){
if(vis[j]) sm += nn-sz[x];
else sm += sz[j];
}
if(sm) g.pb(sm);
}
if(g.size() > 1){
ll sm = g[0];
for(ll i= 1; i < g.size() ; i ++){
curr += g[i] * sm;
sm += g[i];
}
ans += curr*2*val[x];
}
for(auto i : com[x]){
vector<ll>gg;
for(auto j : no_name[i]){
if(vis[j]) gg.pb(nn-sz[x]);
else gg.pb(sz[j]);
}
if(gg.size() > 1){
ll smm = gg[0];
ll b = 0;
for(ll j = 1 ; j < gg.size() ; j ++){
b += gg[j] * smm;
smm += gg[j];
}
ans += b * 2;
}
}
for(auto i : tree1[x]){
if(vis[i]){
ans += h * (nn-sz[x]) * 2;
}
else{
ans += h * sz[i] * 2;
dfs_get(i);
}
}
}
void solve()
{
cin >> n >> m;
for(ll i= 1; i <= m; i ++){
ll x,y;
cin >> x >> y;
v[x].pb(y);
v[y].pb(x);
}
for(int i= 1; i <= n; i ++){
if(!tin[i]) dfs_br(i,i);
}
ctr = 1;
for(ll i= 1; i <= n ; i ++){
if(!node[i]) dfs(i),ctr ++;
}
ctr --;
for(ll i= 1; i <= ctr; i ++){
if(!vis[i]) dfs_tr(i);
}
for(ll i= 1; i <= ctr ; i ++) vis[i] = 0;
for(ll i= 1; i <= ctr ; i ++){
if(!vis[i]){
nn = sz[i];
dfs_get(i);
}
}
cout << ans << endl;
}
int main(){
//ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
//freopen(".in" , "r" , stdin);freopen(".out" , "w" , stdout);
int t = 1;
//cin >> t;
while(t--) {solve() ; }
}
Compilation message (stderr)
count_triplets.cpp: In function 'void dfs_get(long long int)':
count_triplets.cpp:118:24: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
118 | for(ll i= 1; i < g.size() ; i ++){
| ~~^~~~~~~~~~
count_triplets.cpp:134:30: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
134 | for(ll j = 1 ; j < gg.size() ; j ++){
| ~~^~~~~~~~~~~
# | 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... |