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
4
2 1 4 3
3 4 2 1
4
2 1 3 4
-1
5
2 3 4 5 1
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 }
以上是关于Square Root of Permutation - CF612E的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode Sum of Square Numbers