Square Root of Permutation - CF612E

Descriptionide

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].spa

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.3d

Inputcode

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

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

Outputci

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

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.input

Sample Inputit

 
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代碼
相關文章
相關標籤/搜索