QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#837593 | #9772. Permutation Routing | nhuang685 | TL | 0ms | 3528kb | C++23 | 5.5kb | 2024-12-30 08:52:08 | 2024-12-30 08:52:09 |
Judging History
answer
/**
* @author n685
* @date 2024-12-29 16:25:30
*/
#include "bits/stdc++.h"
#ifdef LOCAL
#include "dd/debug.h"
#else
#define dbg(...) 42
#define dbg_proj(...) 420
#define dbg_rproj(...) 420420
void nline() {}
void bar() {}
void start_clock() {}
void end_clock() {}
#endif
namespace rs = std::ranges;
namespace rv = std::views;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;
void solve() {
int n;
std::cin >> n;
std::vector<int> p(n);
for (int& v : p) {
std::cin >> v;
--v;
}
std::vector<std::vector<std::pair<int, int>>> adj(n);
std::vector<std::pair<int, int>> edges;
for (int i = 0; i < n - 1; ++i) {
int u, v;
std::cin >> u >> v;
--u;
--v;
adj[u].emplace_back(i, v);
adj[v].emplace_back(i, u);
edges.emplace_back(u, v);
}
auto sep = [&](int i, int j) {
return edges[i].first != edges[j].first && edges[i].first != edges[j].second
&& edges[i].second != edges[j].first
&& edges[i].second != edges[j].second;
};
std::vector<std::vector<int>> ans;
auto apply = [&](std::vector<int> v) {
if (v.empty()) {
return;
}
rs::sort(v);
v.erase(rs::unique(v).begin(), v.end());
if (ans.empty()) {
for (int i : v) {
std::swap(p[edges[i].first], p[edges[i].second]);
}
ans.push_back(v);
return;
}
ans.emplace_back();
for (int i : v) {
std::swap(p[edges[i].first], p[edges[i].second]);
bool g = true;
for (int j : ans.end()[-2]) {
if (!sep(i, j)) {
g = false;
break;
}
}
if (g) {
ans.end()[-2].push_back(i);
} else {
ans.back().push_back(i);
}
}
if (ans.back().empty()) {
ans.pop_back();
} else if (ans.end()[-2] == ans.back()) {
ans.pop_back();
ans.pop_back();
}
};
std::vector<int> sub(n), rem(n);
auto comp_sub = [&](auto&& self, int node, int par) -> void {
sub[node] = 1;
for (auto [t, i] : adj[node]) {
if (i == par || rem[i]) {
continue;
}
self(self, i, node);
sub[node] += sub[i];
}
};
auto cent = [&](auto&& self, int node, int par, int sz) -> int {
for (auto [t, i] : adj[node]) {
if (i == par || rem[i]) {
continue;
}
if (2 * sub[i] > sz) {
return self(self, i, node, sz);
}
}
return node;
};
std::vector<int> bel(n);
auto comp_bel_dfs = [&](auto&& self, int node, int par, int val) -> void {
bel[node] = val;
for (auto [t, i] : adj[node]) {
if (i != par && !rem[i]) {
self(self, i, node, val);
}
}
};
auto comp_bel = [&](int rt) -> void {
bel[rt] = -1;
for (auto [t, i] : adj[rt]) {
if (!rem[i]) {
comp_bel_dfs(comp_bel_dfs, i, rt, t);
}
}
};
auto good = [&](int node) -> bool { return bel[node] == bel[p[node]]; };
auto phase1_dfs =
[&](auto&& self, int node, int par, std::vector<int>& fl, bool cc) -> void {
bool g = cc && (good(node) || bel[p[node]] == -1);
for (auto [t, i] : adj[node]) {
if (i == par || rem[i]) {
continue;
}
bool ch = true;
if (g && !good(i)) {
ch = false;
fl.push_back(t);
g = false;
}
self(self, i, node, fl, ch);
}
};
auto phase1 = [&](int rt, std::vector<int>& fl) -> void {
for (auto [t, i] : adj[rt]) {
if (!rem[i]) {
phase1_dfs(phase1_dfs, i, rt, fl, true);
}
}
};
auto gen = [&](auto&& self, int rt) -> void {
comp_sub(comp_sub, rt, -1);
rt = cent(cent, rt, -1, sub[rt]);
dbg(rt);
comp_bel(rt);
// while (true) {
// std::vector<int> fl;
// phase1(rt, fl);
// if (fl.empty()) {
// break;
// }
// apply(fl);
// }
while (true) {
std::vector<int> fl1;
for (auto [t, i] : adj[rt]) {
if (p[i] != i && !rem[i] && !good(i)) {
fl1.push_back(t);
break;
}
}
if (fl1.empty()) {
for (auto [t, i] : adj[rt]) {
if (!rem[i] && !good(i)) {
fl1.push_back(t);
break;
}
}
if (fl1.empty()) {
break;
}
}
bool ep = fl1.empty();
for (auto [t, i] : adj[rt]) {
if (!rem[i]) {
phase1_dfs(phase1_dfs, i, rt, fl1, ep || fl1[0] != t);
}
}
apply(fl1);
std::vector<int> fl2;
for (auto [t, i] : adj[rt]) {
if (!rem[i] && bel[p[rt]] == t) {
fl2.push_back(t);
break;
}
}
// phase1(rt, fl2);
ep = fl2.empty();
for (auto [t, i] : adj[rt]) {
if (!rem[i]) {
phase1_dfs(phase1_dfs, i, rt, fl2, ep || fl2[0] != t);
}
}
if (!fl2.empty()) {
apply(fl2);
}
}
rem[rt] = true;
for (auto [t, i] : adj[rt]) {
if (!rem[i]) {
self(self, i);
}
}
};
gen(gen, 0);
std::cout << ans.size() << '\n';
for (const auto& v : ans) {
std::cout << v.size();
for (int i : v) {
std::cout << ' ' << i + 1;
}
std::cout << '\n';
}
}
int main() {
#ifndef LOCAL
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
#endif
int t;
std::cin >> t;
for (int i = 0; i < t; ++i) {
dbg(i + 1);
solve();
bar();
}
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 0ms
memory: 3528kb
input:
1 5 1 4 2 5 3 1 2 2 3 2 4 1 5
output:
6 2 2 4 1 1 1 2 1 3 1 1 1 4
result:
ok ok, up to 6 steps were used
Test #2:
score: -100
Time Limit Exceeded
input:
10000 5 2 3 1 5 4 1 5 3 2 1 2 1 4 5 1 2 3 4 5 2 3 3 4 2 1 4 5 5 4 2 5 1 3 3 5 2 3 4 1 3 1 5 1 3 4 2 5 5 3 2 1 1 3 2 4 5 1 2 3 4 5 2 1 3 5 2 3 5 4 5 1 2 3 4 5 4 5 3 4 4 2 4 1 5 5 2 1 4 3 2 1 5 1 3 1 1 4 5 4 1 2 5 3 3 1 5 1 1 2 1 4 5 5 3 4 2 1 3 1 3 5 4 3 3 2 5 3 4 1 2 5 3 2 3 5 1 5 3 4 5 3 4 1 2 5 2 ...