• Square Root of Permutation


    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代码
  • 相关阅读:
    stompjs使用
    WKWebView新窗口打开链接
    iOS实现自定义拍照页面
    Universal Link
    社群app开发问题记录
    C#中try catch finally
    如何生成代码项目的工程结构
    C# SqlSugar基于 .NET 开源ORM框架
    C# DataGridView 行和列的操作
    禁止EditText 自动弹出软键盘
  • 原文地址:https://www.cnblogs.com/Randolph87/p/5199243.html
Copyright © 2020-2023  润新知