Submission #396656

#TimeUsernameProblemLanguageResultExecution timeMemory
396656AriaHDuathlon (APIO18_duathlon)C++11
100 / 100
190 ms73108 KiB
/** 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 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...