E. Square Root of Permutation

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 = q^2 = [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 q^2 = 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 test(s)
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

数组表示的就是映射关系 如a[1] = 2;就表示为1 -> 2;但是题目给定是i -> (a[i]) -> a[j] (a[j] = a[a[i]]);现在我们知道i和a[j]要求的是a[i];

置换的预备知识:
(a1,a2,a3)表示a1->a2,a2->a3,a3->a1;由于映射为一一对应关系,具有可逆性;(求解的依据)
对于一个置换(a1…an)一定可以划分为若干个不相交的循环
如(2,1,4,3) 变成置换之后为(1,2)(3,4)
特别注意循环乘法之间拆合关系(逆推原始的循环)以及元素位置的改变(得到答案): ans[位置] = val;

对于循环里面的元素个数为奇数时,(a[1],a[2],a[3])(a[1],a[2],a[3]) = (a[1],a[3],a[2]);即 a[1]->a[2]->a[3] ==>a[1]->a[3];同理a[2]->a[3]->a[1] ==>a[2]->a[1]; a[3] ->a[2];扩展到size = 2k+1个数的循环相乘呢?很容易知道当下标从0开始时;每个数的位置变成了2*i%size;同时告诉我们,循环的大小为奇数时,可以由自己生成,所以不用去管奇数的是否配对;

为偶数时:如(a1,a2,a3,a4)^2 = (a1,a3)(a2,a4);这就告诉我们,当p中分解出来的一个循环的大小为偶数时,循环只能由一个2*n的循环分裂得到(那我们在你想得到答案时就需要两个2k大小的循环合并成一个大小为4k的循环),在这时判断是否无解;偶数大小的循环平方时个数二分;而奇数只是把同奇偶(以下标看奇偶)的合并在一起了;

在编码时,开始就是用了循环分解算法,分解成cnt个循环节;可能会怀疑为什么这就是在一个循环里面呢?依上面的置换乘积可以看出循环大小为奇数时,只是调换了元素的对应关系,但是并没有改变ai的值,所以我们只需按照这个调换关系,逆着推回去即可;(奇偶调换两次就等于没调换~~),如果是偶数,那么分裂后还在一个循环中的元素,之前一定在同一个循环中,所以只需能配对就可以得到配对的两个的父循环~~(逆推的原理,也是理解的关键)

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1e6+;
int B[MAXN],vis[MAXN],ans[MAXN],id[MAXN];
vector<int> v[MAXN];
#define pb push_back
bool cmp(const vector<int> &a,const vector<int> &b)
{
return a.size() < b.size();
}
int main()
{
int i,n,cnt = ,tot = ;
cin>>n;
for(i = ;i <= n;i++)
scanf("%d",B+i);
for(i = ;i <= n;i++)if(vis[i] != ){
int tmp = i;
++cnt;
do{
vis[tmp] = ;
v[cnt].pb(tmp);
tmp = B[tmp];
}while(tmp != i);
}
sort(v+,v++cnt,cmp);
for(i = ;i <= cnt;i++){
int sz = v[i].size();
if(sz & ){
for(int k = ;k < sz;k++)
id[k*%sz] = v[i][k];
for(int k = ;k < sz;k++)
ans[id[k]] = id[(k+)%sz];
}
else if(sz == v[i+].size()){
for(int k = ;k < sz;k++){
ans[v[i][k]] = v[i+][k];
ans[v[i+][k]] = v[i][(k+)%sz];
}
i++;
}
else{
return puts("-1"),;
}
}
for(i = ;i <= n;i++){
printf("%d ",ans[i]);
}
}
 
    -

Codeforces 612E - Square Root of Permutation的更多相关文章

  1. Codeforces.612E.Square Root of Permutation(构造)

    题目链接 \(Description\) 给定一个\(n\)的排列\(p_i\),求一个排列\(q_i\),使得对于任意\(1\leq i\leq n\),\(q_{q_i}=p_i\).无解输出\( ...

  2. codefroces 612E Square Root of Permutation

    A permutation of length n is an array containing each integer from 1 to n exactly once. For example, ...

  3. [CF 612E]Square Root of Permutation

    A permutation of length n is an array containing each integer from 1 to n exactly once. For example, ...

  4. Square Root of Permutation - CF612E

    Description A permutation of length n is an array containing each integer from 1 to n exactly once. ...

  5. CF612E Square Root of Permutation

    题目分析 我们首先模拟一下题意 假设有一个 \(q _1\) \(p\) \(a_1\) \(a_x\) \(a_{a_1}\) \(a_{a_x}\) \(q\) \(x\) \(a_1\) \(a ...

  6. Codeforces 715A & 716C Plus and Square Root【数学规律】 (Codeforces Round #372 (Div. 2))

    C. Plus and Square Root time limit per test 2 seconds memory limit per test 256 megabytes input stan ...

  7. Codeforces Round #372 (Div. 1) A. Plus and Square Root 数学题

    A. Plus and Square Root 题目连接: http://codeforces.com/contest/715/problem/A Description ZS the Coder i ...

  8. Codeforces 715A. Plus and Square Root[数学构造]

    A. Plus and Square Root time limit per test 2 seconds memory limit per test 256 megabytes input stan ...

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

随机推荐

  1. C++中如何修改const变量

      一.结论 声明:不同于C语言的const变量修改问题(可以通过指针间接修改const变量的值),这里只讨论C++ 里的const. C++ const 修饰符,表示常量,即如果以后保证不会修改则声 ...

  2. WordPress搭建Personal Blog

    早就想搭建一个专属于自己的博客了,用来记录自己生活.学习的点点滴滴.之所以选WordPress,主要是因为它可以支持Latex,而且特别喜欢其简约的风格. WordPress有个the famous ...

  3. windows 7 共享,未授予用户在此计算机上的请求登录类型

    刚刚重装了windows7,新下载的一个ghost版本,结果却不能共享,每次访问这台机器的共享都提示, 未授予用户在此计算机上的请求登录类型 这个情况好像是存在于win7访问win7,我用一台XP系统 ...

  4. linux 常识笔记 20160621

    Linux分四部分 Linux内核 GNU工具组建 图形化桌面环境 应用软件 Linux系统的核心是内核,内核控制着计算机系统上的所有硬件和软件:必要时分配硬件,有需要时执行软件. 内核负责四项主要功 ...

  5. 优化sql,返回行数少情况下,NL比hash快好多

    sql如下 select t.id, t.value, tt.sort as sortno from ENGINEERING_TYPE t left join ENGINEERING_TYPE tt ...

  6. Intent的介绍

    一.Intent的介绍 Intent的中文意思是“意图,意向”,在Android中提供了Intent机制来协助应用间的交互与通讯,Intent负责对应用中一次操作 的动作.动作涉及数据.附加数据进行描 ...

  7. c++与c不太相同的一些地方2

    1.一般全局变量放到cpp 文件里面,而不是.h 里面.要不然容易乱套,这个乱几次就好了,先记住这样一种编码规范. 以为大家都引入就比较麻烦,但是实现起来就只有cpp里面才有.毕竟.h是要被包含的文件 ...

  8. C#总结1

    C#摘要 第一章: 数据类型: 在定义变量的时候,记下规则,开头不能是数字,变量名只能包括 字母 “_” 数字 整型类型 名称 CTS类型 说明 范围 sbyte System.SByte 8位有符号 ...

  9. C# string类型遇到的两个问题

    最近在维护一位离职的同事写的WPF代码,偶然发现他使用C# string类型的两个问题,在这里记录一下. 1. 使用Trim函数移除字串中的空格.换行符等字符串. csRet.Trim(new cha ...

  10. file_up

    一.接收数据 表单提交的数据会自动封装为数组 用$_GET, $_POST, 或$_REQUEST获得表单提交的数据;   二.文件上传的相关配置 1.表单设置: 要进行文件的上传,需要对form表单 ...