题意:给出一个1到n的序列,定义运算p[I] = q[q[I]],q为p的平方根,现在给出p,求出任意一个符合题意的q。
思路:将序列视为一个有向图,对于每个位置,将I和p[I]之间连一条边,可以发现,一个序列是由若干不相交的环组成的,而且对于平方运算,奇环长度不变,偶环分裂成两个小的环,所以可以将p中所有的环求出来。
对于奇环,认为他们原先是由奇环组成的,并求出原先的奇环
对于偶环,将两个长度相等的偶环合并,如果合并后还有剩余的偶环,则不存在平方根。
#include <bits/stdc++.h>
#define eps 1e-6
#define LL long long
#define pii pair<int, int>
#define pb push_back
#define mp make_pair
//#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
const int MAXN = 1000100;
//const int INF = 0x3f3f3f3f;
int n;
int a[MAXN];
int ans[MAXN];
bool vis[MAXN];
vector< vector<int> > cyc[MAXN];
bool check() {
for (int i = 1; i <= n; i++)
if (!(i&1) && (cyc[i].size()&1))
return false;
return true;
}
void work() {
for (int i = 1; i <= n; i++) {
if (i&1) {
for (int j = 0; j < cyc[i].size(); j++) {
for (int k = 0; k < i; k++)
ans[cyc[i][j][k]] = a[ cyc[i][j][(k+(i-1)/2)%i] ];
}
}
else {
for (int j = 0; j < cyc[i].size(); j+=2) {
for (int k = 0; k < i; k++) {
ans[cyc[i][j][k]] = a[ cyc[i][j+1][(i+k-1)%i] ];
ans[cyc[i][j+1][k]] = a[ cyc[i][j][k] ];
}
}
}
}
}
int main()
{
//freopen("input.txt", "r", stdin);
scanf("%d", &n);
for (int i = 1; i <= n; i++)
scanf("%d", &a[i]);
for (int i = 1; i <= n; i++) if (!vis[i]) {
vector<int> tmp;
int pos = i;
do {
vis[pos] = true;
tmp.pb(pos);
pos = a[pos];
} while (pos != i);
cyc[tmp.size()].pb(tmp);
}
if (!check()) puts("-1");
else {
work();
for (int i = 1; i <= n; i++)
printf("%d ", ans[i]);
}
return 0;
}