Submission #105406

#TimeUsernameProblemLanguageResultExecution timeMemory
105406luciocfIdeal city (IOI12_city)C++14
32 / 100
1077 ms17628 KiB
#include <bits/stdc++.h>

// just testing

#define ff first
#define ss second

using namespace std;

const int maxn = 1e5+10;
const int mod = 1e9;

typedef pair<int, int> pii;

int n;
pii pt[maxn];

int vert[maxn], A[maxn];

vector<int> grafo[maxn];

map<pii, int> ind, conecta;

int nivel[maxn];

bool comp(pii a, pii b)
{
	if (a.ss == b.ss) return a.ff < b.ff;
	return a.ss < b.ss; 
}

void init()
{
	ind.clear(); conecta.clear();
	for (int i = 1; i <= n; i++)
		grafo[i].clear(), A[i] = 0;
}

int make_tree1(void)
{
	sort(pt+1, pt+n+1);
	for (int i = 1; i <= n; i++)
		ind[pt[i]] = i;

	int atual = 1;
	vert[1] = 1, A[1] = 1;

	for (int i = 2; i <= n; i++)
	{
		if (pt[i].ff > pt[i-1].ff || pt[i].ss-pt[i-1].ss > 1)
		{
			vert[i] = ++atual;
			A[atual]++;
			continue;
		}

		vert[i] = atual;
		A[atual]++;
	}

	for (int i = 1; i <= n; i++)
	{
		if (ind.find({pt[i].ff-1, pt[i].ss}) != ind.end())
		{
			int u = i, v = ind[{pt[i].ff-1, pt[i].ss}];
			u = vert[u], v = vert[v];

			if (!conecta[{u, v}])
			{
				conecta[{u, v}] = conecta[{v, u}] = 1;
				grafo[u].push_back(v), grafo[v].push_back(u);
			}
		}
	}

	return atual;
}

int make_tree2(void)
{
	sort(pt+1, pt+n+1, comp);
	for (int i = 1; i <= n; i++)
		ind[pt[i]] = i;

	int atual = 1;
	vert[1] = 1, A[1] = 1; 

	for (int i = 2; i <= n; i++)
	{
		if (pt[i].ss > pt[i-1].ss || pt[i].ff-pt[i-1].ff > 1)
		{
			vert[i] = ++atual;
			A[atual]++;
			continue;
		}

		vert[i] = atual;
		A[atual]++;
	}

	for (int i = 1; i <= n; i++)
	{
		if (ind.find({pt[i].ff, pt[i].ss-1}) != ind.end())
		{
			int u = i, v = ind[{pt[i].ff, pt[i].ss-1}];
			u = vert[u], v = vert[v];

			if (!conecta[{u, v}])
			{
				conecta[{u, v}] = conecta[{v, u}] = 1;
				grafo[u].push_back(v), grafo[v].push_back(u);
			}
		}
	}

	return atual;
}

void dfs(int u, int p)
{
	for (auto v: grafo[u])
	{
		if (v == p) continue;

		nivel[v] = nivel[u]+1;
		dfs(v, u);
	}
}

int DistanceSum(int N, int *X, int *Y)
{
	int ans = 0;
	n = N;
	for (int i = 1; i <= n; i++)
		pt[i] = {X[i-1], Y[i-1]};

	int m = make_tree1();

	for (int i = 1; i <= m; i++)
	{
		nivel[i] = 0;
		dfs(i, 0);

		for (int j = 1; j < i; j++)
		{
			long long soma = (1ll*A[j]*nivel[j]*A[i])%mod;
			ans = (ans+soma)%mod;
		}
	}

	init();
	m = make_tree2();

	for (int i = 1; i <= m; i++)
	{
		nivel[i] = 0;
		dfs(i, 0);

		for (int j = 1; j < i; j++)
		{
			long long soma = (1ll*A[j]*nivel[j]*A[i])%mod;
			ans = (ans+soma)%mod;
		}
	}

	return ans;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...