Square Root of Permutation - CF612E

Posted Randolph87

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Square Root of Permutation - CF612E相关的知识,希望对你有一定的参考价值。

Description

A permutation of length n is an array containing each integer from 1 to n exactly once. For example, q = [4, 5, 1, 2, 3] is a permutation. For the permutation q the square of permutation is the permutation p that p[i] = q[q[i]] for each i = 1... n. For example, the square of q = [4, 5, 1, 2, 3] is p = q2 = [2, 3, 4, 5, 1].

This problem is about the inverse operation: given the permutation p you task is to find such permutation q that q2 = p. If there are several such q find any of them.

Input

The first line contains integer n (1 ≤ n ≤ 106) — the number of elements in permutation p.

The second line contains n distinct integers p1, p2, ..., pn (1 ≤ pi ≤ n) — the elements of permutation p.

Output

If there is no permutation q such that q2 = p print the number "-1".

If the answer exists print it. The only line should contain n different integers qi (1 ≤ qi ≤ n) — the elements of the permutation q. If there are several solutions print any of them.

Sample Input

 
Input
4
2 1 4 3
Output
3 4 2 1

Input
4
2 1 3 4
Output
-1
Input
5
2 3 4 5 1
Output
4 5 1 2 3

简单题意

给出一个大小为n的置换群p,求一个置换群q,使得q^2=p

胡说题解

首先我们观察q^2是怎么运算的,置换群可以看成一个一个的环,每个点i向a[i]连一条边就是那个图

q^2其实就是把i的边变成a[a[i]],也就是在环上走两步,然后q原本的环就变了

1.假设原来是奇数环,那么后来还是一个奇数环,只是顺序变了

2.假设原来是偶数环,那么就会拆成两个大小为一半的环

我们再看p

p上的奇数环可能是原来的奇数环,也有可能是偶数环拆开得来的

p上的偶数环只可能是原来的偶数环拆开得来

对于奇数环我们只要把这个环的后半部分与前半部分(先把这个环断开)交替插入就可以构造出原来的那个奇数环

对于偶数环我们就只能找一个相同大小的偶数环交替插入,即两个相同大小的偶数环合并,如果找不到相同大小的偶数环,那么我们就知道不存在这样的q使得q^2=p

 1 #include<cstdio>
 2 #include<algorithm>
 3 using namespace std;
 4 
 5 const int maxn=1000100;
 6 
 7 int n,tot,a[maxn],b[maxn],s[maxn],l[maxn],cir[maxn];
 8 bool flag[maxn];
 9 
10 bool com(int a,int b){
11     return l[a]<l[b];
12 }
13 
14 int main(){
15     scanf("%d",&n);
16     int i,j,k;
17     for(i=1;i<=n;i++)scanf("%d",&a[i]);
18     for(i=1;i<=n;i++)
19     if(!flag[i]){
20         cir[++tot]=i;
21         flag[i]=true;
22         ++l[i];
23         j=a[i];
24         while(!flag[j]){
25             flag[j]=true;
26             ++l[i];
27             j=a[j];
28         }
29     }
30     sort(cir+1,cir+1+tot,com);
31     int x=0;
32     bool f=true;
33     for(i=1;i<=tot;i++)
34     if((l[cir[i]]&1)== 0){
35         if(x==0)x=l[cir[i]];
36         else
37         if(x==l[cir[i]])x=0;
38         else f=false;
39     }
40     if(x!=0)f=false;
41     if(f==false)printf("-1");
42     else{
43         for(i=1;i<=tot;i++){
44             if((l[cir[i]]&1)==1){
45                 j=cir[i];
46                 k=0;
47                 while(flag[j]){
48                     s[k]=j;
49                     flag[j]=false;
50                     k=(k+2)%l[cir[i]];
51                     j=a[j];
52                 }
53                 for(j=0;j<l[cir[i]]-1;j++)b[s[j]]=s[j+1];
54                 b[s[l[cir[i]]-1]]=s[0];
55             }
56             else{
57                 j=cir[i];
58                 k=cir[i+1];
59                 while(flag[j]){
60                     b[j]=k;
61                     b[k]=a[j];
62                     flag[j]=false;
63                     flag[k]=false;
64                     j=a[j];
65                     k=a[k];
66                 }
67                 ++i;
68             }
69         }
70         for(i=1;i<=n;i++)printf("%d ",b[i]);
71     }
72     return 0;
73 }
AC代码

 

以上是关于Square Root of Permutation - CF612E的主要内容,如果未能解决你的问题,请参考以下文章

next_permutatio

LeetCode Sum of Square Numbers

#Leetcode# 633. Sum of Square Numbers

633. Sum of Square Numbers

633. Sum of Square Numbers

卡方检验 (Chi-square test / Chi-square goodness-of-fit test)