Submission #1347899

#TimeUsernameProblemLanguageResultExecution timeMemory
1347899vladmart09Paths (BOI18_paths)C++20
100 / 100
126 ms103840 KiB

#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <random>
#include <queue>
#include <numeric>
#include <array>
#include <iomanip>
#include <stack>
#include <chrono>
#include <climits>

using namespace std;

using ll = long long;
using ld = long double;
using vi = vector<ll>;
using vii = vector<vi>;
using viii = vector<vii>;
using pi = pair<ll, ll>;
using vpi = vector<pi>;
using vb = vector<bool>;
using vs = vector<string>;

#define vec vector
#define cmax(x, y) x = max({x, y})
#define cmin(x, y) x = min({x, y})
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()

const ll N = 3e5 + 5, MOD = 1e9 + 7, INF = (ll)1e18, K = 20;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

ll n, m, k, a[N], cnt[N][5], cnt2[N][5][5], sum[N][5];
vi g[N];
vpi e;

void solve() {
	cin >> n >> m >> k;

	for (ll i = 1; i <= n; i++) cin >> a[i], a[i]--;

	ll ans = 0;

	for(ll i = 0; i < m; i++) {
		ll l, r; cin >> l >> r;

		if (a[l] == a[r]) continue;
		e.push_back({ l, r });
		ans += 2;

		g[l].push_back(r);
		g[r].push_back(l);

		cnt[r][a[l]]++;
		cnt[l][a[r]]++;
	}

	for (ll i = 1; i <= n; i++) {
		for (auto& x : g[i]) {
			if (a[x] == a[i]) continue;

			for (ll j = 0; j < k; j++) {
				if (j == a[x] || j == a[i]) continue;

				cnt2[i][a[x]][j] += cnt[x][j];
				sum[i][a[x]] += cnt[x][j];
			}
		}
	}

	if (k >= 3) {
		for (ll i = 1; i <= n; i++) {
			ll sum = 0;
			for (ll j = 0; j < k; j++) {
				ans += sum * cnt[i][j] * 2;
				sum += cnt[i][j];
			}
		}
	}

	if (k >= 4) {
		for (auto& [v, u] : e) {
			for (ll i = 0; i < k; i++) {
				for (ll j = 0; j < k; j++) {
					if (i == j || i == a[v] || i == a[u] || j == a[v] || j == a[u]) continue;

					ans += cnt[v][i] * cnt[u][j] * 2;
				}
			}
		}
	}

	if (k == 5) {
		for (ll i = 1; i <= n; i++) {
			for (ll x = 0; x < k; x++) {
				for (ll y = 0; y < k; y++) {
					if (x == y) continue;

					ans += (sum[i][x] - cnt2[i][x][a[i]] - cnt2[i][x][x] - cnt2[i][x][y]) * (sum[i][y] - cnt2[i][y][a[i]] - cnt2[i][y][x] - cnt2[i][y][y]);

					for (ll z = 0; z < k; z++) {
						if (z == x || z == y || z == a[i]) continue;

						ans -= cnt2[i][x][z] * cnt2[i][y][z];
					}
				}
			}
		}
	}

	cout << ans;
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);

	long long tt = 1;
	//cin >> tt;

	while (tt--) {
		solve();
		cout << '\n';
	}

	return 0;
}

/*


Задачу нужно отдельно решать для разных длин путей

2: колво путей
3: с помощью обычного cnt проще всего
4: фиксировать ребро, там все просто
5: фиксировать вершину, сложность в том чтобы не было тле




5 4 5
1 2 3 4 5
1 2
2 3
3 4
4 5




























Какие темы повторить:
1) мст
2) 2сат
3) точки артикуляции
4) ксор базис
5) эйлеровый цикл, путь
6) кмп
7) конвекс хулл
8) вафельное дерево
9) суфиксный массив
10) суффиксный автомат
11) ним

*/
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...