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 int int64_t //be careful about this
using namespace std;
#define vt vector
#define ar array
#define pr pair
#define f first
#define s second
#define pb push_back
#define eb emplace_back
#define fr(i,a,b) for(int i = (a); i < (b); ++i)
#define rf(i,a,b) for(int i = (b)-1; i >= (a); --i)
#define all(x) x.begin(),x.end()
#define mem(a,b) memset(a,b,sizeof(a))
namespace IN{
template<class T> void re(vector<T> &A);
template<class S,class T> void re(pair<S,T> &A);
template<class T,size_t N> void re(array<T,N> &A);
template<class T> void re(T& x){
cin >> x;}
template<class H, class... T> void re(H& h, T&... t){
re(h); re(t...);}
template<class T> void re(vector<T> &A){
for(auto& x : A) re(x);}
template<class S,class T> void re(pair<S,T> &A){
re(A.first); re(A.second);}
template<class T,size_t N> void re(array<T,N> &A){
for(int i = 0; i < N; ++i) re(A[i]);}
}
namespace OUT{
template<class T>
void __p(const T& a){ cout<<a; }
template<class T, class F>
void __p(const pair<T, F>& a){ cout<<"{"; __p(a.first); cout<<","; __p(a.second); cout<<"}\n"; }
template<class T, size_t N>
void __p(const array<T,N>& a){ cout<<"{"; for(int i=0;i<N;++i)__p(a[i]),cout<<",}\n"[i+1==N]; }
template<class T>
void __p(const vector<T>& a){
cout<<"{";for(auto it=a.begin();it<a.end();it++)__p(*it),cout<<",}\n"[it+1==a.end()]; }
template<class T, class ...Arg>
void __p(T a1, Arg ...a){__p(a1); __p(a...); }
template<class Arg1>
void __f(const char *s, Arg1 &&arg1){ cout<<s<<" : "; __p(arg1); cout<<endl; }
template<class Arg1, class ... Args>
void __f(const char *ss, Arg1 &&arg1, Args &&... args){
int b=0,i=0; do{ if(ss[i]=='(') b++; if(ss[i]==')') b--; i++;}while(!(ss[i]==','&&b==0));
const char *comma=ss+i; cout.write(ss,comma-ss)<<" : ";__p(arg1);cout<<" | ";__f(comma+1,args...);}
#define trace(...) cout<<"Line:"<<__LINE__<<" ", __f(#__VA_ARGS__, __VA_ARGS__)
}
namespace FUNC{
void IO(string s = ""){
ios_base::sync_with_stdio(NULL);
cin.tie(nullptr);
cout.precision(20);
cout << fixed;
if(!s.empty()){
freopen((s+".in").c_str(),"r",stdin);
freopen((s+".out").c_str(),"w",stdout);
}
}
const auto start_time = chrono::high_resolution_clock::now();
void output_run_time(){
// will work for ac,cc&&cf.
#ifndef ONLINE_JUDGE
auto end_time = chrono::high_resolution_clock::now();
chrono::duration<double> diff = end_time-start_time;
cout << "\n\n\nTime Taken : " << diff.count();
#endif
}
template<class T> bool ckmin(T& a, const T& b){
return b < a ? a = b, true : false; }
template<class T> bool ckmax(T& a, const T& b){
return a < b ? a = b, true : false; }
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
int my_rand(int L, int R){
return uniform_int_distribution<int>(L,R)(rng); }
template<class T> int sz(const T& x){
return int(x.size()); }
template<class T> int lb(const vector<T>& vec,const T& val){
return int(lower_bound(vec.begin(), vec.end(),val) - vec.begin()); }
template<class T> int ub(const vector<T>& vec,const T& val){
return int(upper_bound(vec.begin(), vec.end(),val) - vec.begin()); }
constexpr int dx[4] = {1,0,-1,0};
constexpr int dy[4] = {0,1,0,-1};
constexpr char dr[4] = {'D','R','U','L'};
constexpr long long INFLL1 = 1e16, INFLL2 = 9e18;
constexpr int INF = 2e9;
template<class T>
vector<T> V(int n,T val){
return vector<T> (n,val);
}
template<class T>
vector<vector<T>> V(int n,int m,T val){
return vector<vector<T>> (n,vector<T> (m,val));
}
template<class T>
vector<vector<vector<T>>> V(int n,int m,int k,T val){
return vector<vector<vector<T>>> (n,vector<vector<T>> (m,vector<T> (k,val)));
}
}
using namespace IN;
using namespace OUT;
using namespace FUNC;
struct edge{
int to;
};
// returns {#bcc components, block tree}.
pair<int,vector<vector<int>>> bi_cc(const vector<vector<edge>> &g){
int n = g.size();
vector<int> depth(n,-1), low(n), comp;
vector<vector<int>> block_tree(n);
stack<int> s;
int z = 0, f = -1;
auto dfs = [&](auto self,int node,int parent) -> void {
low[node] = depth[node];
for(auto [child] : g[node])
if(child != parent){
if(depth[child] < 0){
s.push(f); int here = f; --f;
s.push(child); s.push(node);
depth[child] = depth[node] + 1;
self(self,child,node);
if(low[child] >= depth[node]){
while(comp.empty() || comp.back() != here)
comp.push_back(s.top()), s.pop();
sort(all(comp));
comp.erase(unique(all(comp)),comp.end());
for(auto i : comp) if(i >= 0) block_tree[i].pb(n+z);
comp = {};
z++;
}
low[node] = min(low[node],low[child]);
}else if(depth[child] < depth[node]){
s.push(child); s.push(node);
low[node] = min(low[node],depth[child]);
}
}
return;
};
for(int i = 0; i < n; ++i)
if(depth[i] < 0){
depth[i] = 0;
dfs(dfs,i,-1);
}
block_tree.resize(z + n);
fr(i,0,n){
for(auto j : block_tree[i]){
assert(j >= n);
block_tree[j].pb(i);
}
}
return {z,block_tree};
}
signed main(){
IO();
int n,m;
re(n,m);
vt<vt<edge>> g(n);
fr(e,0,m){
int u,v; re(u,v); --u,--v;
g[u].pb({v}); g[v].pb({u});
}
auto [z,block_tree] = bi_cc(g);
vt<int> ss(z + n,0);
vt<bool> vis(z + n, false);
fr(i,0,n) ss[i] = 1;
auto dfs = [&](auto self,int node,int parent) -> void {
vis[node] = true;
for(auto child : block_tree[node])
if(child != parent){
self(self,child,node);
ss[node] += ss[child];
}
};
fr(i,0,z+n) if(!vis[i]) dfs(dfs,i,-1);
fr(i,0,z+n) vis[i] = false;
int ans = 0;
auto re_root = [&](auto self,int node,int parent) -> void {
vis[node] = true;
if(node >= n){
for(auto child : block_tree[node])
ans -= (sz(block_tree[node]) - 1) * ss[child] * ss[child];
}
for(auto child : block_tree[node])
if(child != parent){
ss[node] -= ss[child];
ss[child] += ss[node];
self(self,child,node);
ss[child] -= ss[node];
ss[node] += ss[child];
}
};
fr(i,0,z+n){
if(!vis[i]){
ans += ss[i] * (ss[i] - 1) * (ss[i] - 1);
re_root(re_root,i,-1);
}
}
cout << ans;
//output_run_time();
return 0;
}
Compilation message (stderr)
count_triplets.cpp: In function 'void FUNC::IO(std::string)':
count_triplets.cpp:68:14: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
68 | freopen((s+".in").c_str(),"r",stdin);
| ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
count_triplets.cpp:69:14: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
69 | freopen((s+".out").c_str(),"w",stdout);
| ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# | 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... |