This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
/** vaziat sorati ghermeze **/
#pragma GCC optimize("O2")
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
#define all(x) (x).begin(),(x).end()
#define F first
#define S second
#define Mp make_pair
#define SZ(x) (int)x.size()
#define fast_io ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define file_io freopen("in.txt" , "r+" , stdin) ; freopen("out.txt" , "w+" , stdout);
const int N = 1e6 + 10;
const ll mod = 1e9 + 7;
const ll mod2 = 998244353;
const ll inf = 8e18;
const int LOG = 22;
ll pw(ll a , ll b, ll M) { return (!b ? 1 : (b & 1 ? (a * pw(a * a % M, b / 2, M)) % M : pw(a * a % M, b / 2, M))); }
ll tot;
int n, m, ts, H[N], Up[N], mark[N], sub[N];
vector < int > vec, G[N], adj[N];
void dfs(int v, int P = 0)
{
Up[v] = H[v] = H[P] + 1;
mark[v] = 1;
for(auto u : G[v])
{
if(u == P) continue;
if(mark[u])
{
Up[v] = min(Up[v], H[u]);
continue;
}
int last = SZ(vec);
dfs(u, v);
if(Up[u] >= H[v])
{
ts ++;
vec.push_back(v);
while(SZ(vec) > last)
{
int node = vec.back();
vec.pop_back();
adj[ts].push_back(node);
adj[node].push_back(ts);
///printf("yal %d - %d\n", ts, node);
}
}
Up[v] = min(Up[v], Up[u]);
}
vec.push_back(v);
}
void pre(int v, int P = 0)
{
mark[v] = 1;
sub[v] = (v <= n);
for(auto u : adj[v])
{
if(u == P) continue;
pre(u, v);
sub[v] += sub[u];
}
///printf("v = %d sub = %d\n", v, sub[v]);
}
void calc(int v, int P, int _n)
{
if(v <= n)
{
for(auto u : adj[v])
{
if(u == P) continue;
calc(u, v, _n);
}
return;
}
ll p2 = 0;
for(auto u : adj[v])
{
int cu = 0;
if(u == P)
{
cu = _n - sub[v];
}
else
{
cu = sub[u];
}
///printf("v = %d u = %d cu = %d\n", v, u, cu);
p2 += 1ll * cu *cu;
}
///printf("v = %d p2 = %lld\n", v, p2);
for(auto u : adj[v])
{
int cu = 0;
if(u == P)
{
cu = _n - sub[v];
}
else
{
cu = sub[u];
}
tot += 1ll * (_n - cu) * (_n - cu) - p2 + 1ll * cu * cu;
tot += 1ll * (cu - 1) * (_n - cu);
}
for(auto u : adj[v])
{
if(u == P) continue;
calc(u, v, _n);
}
}
int main()
{
scanf("%d%d", &n, &m);
ts = n;
for(int i = 1; i <= m; i ++)
{
int a, b;
scanf("%d%d", &a, &b);
G[a].push_back(b);
G[b].push_back(a);
}
for(int i = 1; i <= n; i ++)
{
if(!mark[i])
{
dfs(i);
}
}
memset(mark, 0, sizeof mark);
for(int i = 1; i <= n; i ++)
{
if(!mark[i])
{
pre(i);
calc(i, 0, sub[i]);
}
}
printf("%lld", tot);
return 0;
}
/** test corner cases(n = 1?) watch for overflow or minus indices **/
Compilation message (stderr)
count_triplets.cpp: In function 'int main()':
count_triplets.cpp:128:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
128 | scanf("%d%d", &n, &m);
| ~~~~~^~~~~~~~~~~~~~~~
count_triplets.cpp:133:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
133 | scanf("%d%d", &a, &b);
| ~~~~~^~~~~~~~~~~~~~~~
# | 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... |