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. javascript之css常用属性

    1. position : 属性值有absolute .fixed.relative absolute:生成绝对定位的元素,相对第一父元素进行定位: fixed :   生成绝对定位的元素,相对于浏览 ...

  2. java_客户端防表单重复提交和服务器端session防表单重复提交

    用户输入FormServlet链接 FormServlet-〉form.jsp->DoFormServlet FormServlet:产生token,放在session中 form.jsp:hi ...

  3. 版本和API Level对照表

    版本和API Level对照表 Code name Version API level (no code name) 1.0 API level 1 (no code name) 1.1 API le ...

  4. jsp 用application对象制作留言板

    <%@ page contentType="text/html; charset=gb2312"%> <html> <body> <for ...

  5. opencv拼接相关1

    这里面都是一些比较杂的东西,没什么实际意义.主要是为了,后面能跑一个程序: Stitcher: 抠细节: http://docs.opencv.org/2.4.2/modules/stitching/ ...

  6. uiatuomator提示shortMsg=java.lang.RuntimeException

    自动化要做断言,原本打算使用的testng,因为它断言后就能出结果,还能生成报告,但是在实践过程中,硬是没有成功,所以还是放弃,使用的junit,后面使用的cts框架生成的邮件,现在记录使用junit ...

  7. windows共享文件夹如何让CentOS 6.5读取

    http://www.111cn.net/sys/CentOS/74104.htm 工作需要,需要把本地win7共享的文件夹让CenotOS 6.5服务器临时使用一下,以下是CentOS 6.5系统挂 ...

  8. SharpDevelop 编译时,任务失败,因为未找到“resgen.exe”的解决方法

    在git clone sprite的项目,在本地编译的时候,会出现 任务失败,因为未找到“resgen.exe”,或未安装正确的 Microsoft Windows SDK.任务正在注册表项 HKEY ...

  9. ttt

    <style> .head1{ background:rgb(51,51,51); height:49px; min-width:1241px; width:100%; z-index:1 ...

  10. dedecms自定义函数(二次开发)

    一些功能可能dedecms没有,这个时候可以自己写一些函数: 1.打开inlude->extend.func.php,将函数写到里面 比如:前台: [field:id function=&quo ...