Search for a command to run...
Progressive hints first, then the full explanation and implementation when you're ready to cash out.
Review status
AI-generated and still unreviewed. Double-check the details before internalizing them.
Hints
Open only as much as you need to keep the solve alive.
Think value-by-value, not position-by-position. The final condition is just: for every number , the number of 's in the top row must equal the number of 's in the bottom row.
Each index is a little two-ended object containing and . Swapping it only decides which endpoint goes to the top and which endpoint goes to the bottom.
Build a multigraph where values are vertices and each index is an edge between and . Choosing whether to swap is the same as orienting that edge: top endpoint bottom endpoint.
For a value , top count equals outgoing edges from , and bottom count equals incoming edges to ; loops are already harmless. So we need an orientation with for every vertex.
An undirected multigraph has such a balanced orientation exactly when every vertex has even degree. Then orient each connected component along Euler cycles; whenever the chosen direction disagrees with the original direction , output index as swapped.
Treat every index as an edge. This is the whole problem; the arrays are just wearing a fake mustache.
For every position , we have two values and . After all operations, exactly one of them is in the top array and the other is in the bottom array. So if we draw an edge between vertices and , then choosing the final state of index is choosing an orientation of that edge:
Now look at one value . In the final arrays:
Edges with contribute one to both arrays no matter what, so they are irrelevant. We can ignore loops completely.
Therefore the task becomes:
Can we orient every non-loop edge of an undirected multigraph so that for every vertex , ?
That means every vertex must have even degree. If is odd, then is odd, so the two counts cannot be equal. Impossible.
If every degree is even, each connected component is Eulerian. Take an Euler cycle in each component and orient every traversed edge in the direction it is walked. At every vertex, every time the tour enters it, it also leaves it. Since the tour is closed, this pairs all incident edges into one incoming and one outgoing edge. So every vertex becomes balanced.
That proves the condition is both necessary and sufficient:
Implementation details:
Parallel edges are fine. Disconnected components are fine. Loops were ignored because they are already balanced. No minimization is needed, so this Euler orientation is enough.
Complexity is linear:
per total input size across all test cases, with memory. Fits easily inside the limits; no dark magic, just graph parity doing the heavy lifting.
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
int main() {
setIO();
int T;
cin >> T;
while (T--) {
int n;
cin >> n;
vector<int> a(n + 1), b(n + 1);
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = 1; i <= n; i++) cin >> b[i];
vector<vector<pair<int, int>>> g(n + 1);
vector<int> deg(n + 1, 0);
for (int i = 1; i <= n; i++) {
if (a[i] == b[i]) continue;
g[a[i]].push_back({b[i], i});
g[b[i]].push_back({a[i], i});
deg[a[i]]++;
deg[b[i]]++;
}
bool ok = true;
for (int x = 1; x <= n; x++) {
if (deg[x] % 2) ok = false;
}
if (!ok) {
cout << -1 << '\n';
continue;
}
vector<int> ptr(n + 1, 0), used(n + 1, 0), ans;
for (int start = 1; start <= n; start++) {
while (ptr[start] < (int)g[start].size() && used[g[start][ptr[start]].second]) {
ptr[start]++;
}
if (ptr[start] == (int)g[start].size()) continue;
vector<int> st = {start};
while (!st.empty()) {
int u = st.back();
while (ptr[u] < (int)g[u].size() && used[g[u][ptr[u]].second]) {
ptr[u]++;
}
if (ptr[u] == (int)g[u].size()) {
st.pop_back();
continue;
}
auto [v, id] = g[u][ptr[u]++];
if (used[id]) continue;
used[id] = 1;
if (u == b[id] && v == a[id]) ans.push_back(id);
st.push_back(v);
}
}
cout << ans.size() << '\n';
for (int id : ans) cout << id << ' ';
cout << '\n';
}
return 0;
}#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
int main() {
setIO();
int T;
cin >> T;
while (T--) {
int n;
cin >> n;
vector<int> a(n + 1), b(n + 1);
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = 1; i <= n; i++) cin >> b[i];
vector<vector<pair<int, int>>> g(n + 1);
vector<int> deg(n + 1, 0);
for (int i = 1; i <= n; i++) {
if (a[i] == b[i]) continue;
g[a[i]].push_back({b[i], i});
g[b[i]].push_back({a[i], i});
deg[a[i]]++;
deg[b[i]]++;
}
bool ok = true;
for (int x = 1; x <= n; x++) {
if (deg[x] % 2) ok = false;
}
if (!ok) {
cout << -1 << '\n';
continue;
}
vector<int> ptr(n + 1, 0), used(n + 1, 0), ans;
for (int start = 1; start <= n; start++) {
while (ptr[start] < (int)g[start].size() && used[g[start][ptr[start]].second]) {
ptr[start]++;
}
if (ptr[start] == (int)g[start].size()) continue;
vector<int> st = {start};
while (!st.empty()) {
int u = st.back();
while (ptr[u] < (int)g[u].size() && used[g[u][ptr[u]].second]) {
ptr[u]++;
}
if (ptr[u] == (int)g[u].size()) {
st.pop_back();
continue;
}
auto [v, id] = g[u][ptr[u]++];
if (used[id]) continue;
used[id] = 1;
if (u == b[id] && v == a[id]) ans.push_back(id);
st.push_back(v);
}
}
cout << ans.size() << '\n';
for (int id : ans) cout << id << ' ';
cout << '\n';
}
return 0;
}