이 제출은 이전 버전의 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(it == 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);
// cerr << center << "\n";
set <int> noup;
for(auto it:tree[center]) {
noup.insert(it);
if(tin[it] < tin[center]) {
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(tin[child] < tin[center]) continue;
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... |