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

42 1 4 3

Output

3 4 2 1

Input

42 1 3 4

Output

-1

Input

52 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代码

时间: 2024-08-07 01:28:31

Square Root of Permutation - CF612E的相关文章

Project Euler 80:Square root digital expansion 平方根数字展开

Square root digital expansion It is well known that if the square root of a natural number is not an integer, then it is irrational. The decimal expansion of such square roots is infinite without any repeating pattern at all. The square root of two i

UVA 10023 - Square root(手算平方根)

题目:UVA 10023 - Square root(手算平方根) 题目链接 题目大意:求给定的一个数的平方根. 解题思路:用二分但是这个数太大了,就超时了.看题接后发现需要用一种手算平方根的算法. 算法: 先判断这个数是不是偶数位,是的话就第一次取前面的两位数,不是的话第一次就只取前面的一位数来作为被除数.接下来就是两位两位为一节来计算. 用前一次的计算结果乘上20+一个个位数a再乘上这个a,找到最大的a使得这个式子的结果不大于被除数. 被除数减去这个结果然后再在尾巴接上那个大数的接下来两位作

Square Root

Square RootWhen the square root functional configuration is selected, a simplified CORDIC algorithm isused to calculate the positive square root of the input. The input, X_IN, and the output,X_OUT, are always positive and are both expressed as either

Timus 1132 Square Root(二次剩余 解法2)

不理解,背板子 #include<cstdio> using namespace std; int Pow(int a,int b,int p) { int res=1; for(;b;a=1LL*a*a%p,b>>=1) if(b&1) res=1LL*a*res%p; return res; } bool Legendre(int a,int p) { return Pow(a,p-1>>1,p)==1; } void modsqr(int a,int p)

欧拉工程第57题:Square root convergents

题目链接 Java程序 package projecteuler51to60; import java.math.BigInteger; import java.util.Iterator; import java.util.Set; import java.util.TreeSet; class level57{ void solve0(){ /*** a a+2b --- ------- b a+b ***/ int count = 0; BigInteger a=BigInteger.va

Project Euler #80: Square root digital expansion

1 from decimal import getcontext, Decimal 2 3 4 def main(): 5 n = int(raw_input()) 6 p = int(raw_input()) 7 8 getcontext().prec = p+10 # 扩大精度,保证接过 9 sum = 0 10 11 for i in range(1,n+1): 12 nTemp = Decimal(i).sqrt() 13 if nTemp._isinteger() : # 自生函数的判

使用牛顿-拉弗森法定义平方根函数(Newton-Raphson method Square Root Python)

牛顿法(Newton's method)又称为牛顿-拉弗森法(Newton-Raphson method),是一种近似求解实数方程式的方法.(注:Joseph Raphson在1690年出版的<一般方程分析>中提出了后来被称为"牛顿-拉弗森法"的数学方法,牛顿于1671年写成的著作<流数法>中亦包括了这个方法,但该书在1736年才出版.) 之前的一篇博客中提到的二分法可以求解方根,而使用牛顿迭代法可以更快地解出方根.现在,人们使用的计算器里面大多数都是运用的牛顿

UVA - 10023 - Square root (模拟手算开方)

题目传送:UVA - 10023 思路:模拟手算开方,不想用c/c++,感觉太麻烦了,就直接用的java里的BigInteger类来写的,写了好久......Java还是得看看书呀,手算开方参考的这里 AC代码: import java.util.Scanner; import java.math.BigInteger; public class Main { static void fun(BigInteger x) { String str; str = x.toString(); str

69. Sqrt(x) &amp;&amp; 367. Valid Perfect Square

69. Sqrt(x) Implement int sqrt(int x). Compute and return the square root of x. Hide Tags Binary Search Math Hide Similar Problems (M) Pow(x, n) (M) Valid Perfect Square Time Limit Exceed Solution if start from 0. public class Solution { public int m