이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include "split.h"
#include <bits/stdc++.h>
#define int long long
#define inf ((int)1e18)
const int N = 100000;
using namespace std;
vector<int32_t> find_split(int32_t n, int32_t a, int32_t b, int32_t c, vector<int32_t> p, vector<int32_t> q) {
	int m = p.size();
	vector <vector<int> > graph(n), tree(n);
	vector <int> tin(n), tlow(n), sub(n);
	vector <int32_t> ans(n);
	vector <bool> vis(n);
	vector <pair<int, int> > fuck = {{a, 1}, {b, 2}, {c, 3}};
	sort(fuck.begin(), fuck.end()); // sonuncusu çöp
	for(int i = 0; i < m; i++) {
		int a = p[i], b = q[i];
		graph[a].push_back(b);
		graph[b].push_back(a);
	}
	int size = 0;
	auto taguntil = [&](int node, int ata, int tag, vector<vector<int> > &adj, auto&& dfs) -> void {
		size--;
		ans[node] = tag;
		for(auto it:adj[node]) {
			if(node == ata) continue;
			if(size and !ans[it]) dfs(it, node, tag, adj, dfs);
		}
	};
	int time = 0, center = 0;
	auto dfs = [&](int node, int ata, auto&& dfs) -> void {
		tin[node] = time++;
		vis[node] = 1;
		tlow[node] = tin[node];
		sub[node] = 1;
		int mx = 0;
		for(auto it:graph[node]) {
			if(it == ata) continue;
			if(vis[it]) {
				tlow[node] = tlow[it];
			}
			else {
				dfs(it, node, dfs);
				sub[node] += sub[it];
				tree[node].push_back(it);
				tree[it].push_back(node);
				tlow[node] = min(tlow[node], tlow[it]);
			}
			mx = max(sub[it], mx);
		}
		if(mx <= n / 2 and n - sub[node] <= n / 2) {
			center = node;
		}
	};
	dfs(0, 0, dfs);
	set <int> noup;
	for(auto it:tree[center]) {
		noup.insert(it);
		if(tin[it] < tin[center]) {
			cout << "par\n";
			if(n - sub[center] >= fuck[1].first) swap(fuck[1], fuck[0]);
			if(n - sub[center] >= fuck[0].first) {
				size = fuck[0].first;
				taguntil(it, center, fuck[0].second, tree, taguntil);
				size = fuck[1].first;
				taguntil(center, it, fuck[1].second, tree, taguntil);
				for(auto &it:ans) if(!it) it = fuck[2].second;
				return ans;
			}
		}
		else {
			if(sub[it] >= fuck[1].first) swap(fuck[1], fuck[0]);
			if(sub[it] >= fuck[0].first) {
				size = fuck[0].first;
				taguntil(it, center, fuck[0].second, tree, taguntil);
				size = fuck[1].first;
				taguntil(center, it, fuck[1].second, tree, taguntil);
				for(auto &it:ans) if(!it) it = fuck[2].second;
				return ans;
			}
		}
	}
	// worst casede bile bütün subtreeler floor(n / 3)'ten küçük
	int topsize = n -  sub[center];
	for(auto it:tree[center]) {
		if(tin[it] < tin[center]) {
			continue;
		}
		if(tlow[it] < tin[center]) {
			topsize += sub[it];
			noup.erase(it);
		}
		if(topsize >= fuck[1].first) swap(fuck[1], fuck[0]);
		if(topsize >= fuck[0].first) {
			size = fuck[1].first - 1;
			ans[center] = fuck[1].second;
			for(auto child:noup) {
				if(size) taguntil(child, center, fuck[1].second, tree, taguntil);
			}
			size = fuck[0].first;
			taguntil(it, center, fuck[0].second, graph, taguntil);
			for(auto &it:ans) if(!it) it = fuck[2].second;
			return ans;
		}
	}
	return ans;
}
| # | 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... |