Codeforces 612E - Square Root of Permutation
来源:互联网 发布:测手速软件 编辑:程序博客网 时间:2024/06/05 00:32
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
置换的预备知识:->表示映射关系
(a1,a2,a3)表示a1->a2,a2->a3,a3->a1;注意这和题目上给的位置对应的关系不一样,即并不是1->a1,2->a2那种;所以这需要将题目给的信息转换成这种置换关系;(下面没特别说明就是指置换而不是题目给的对应关系)
对于一个置换(a1…an)一定可以划分为若干个不相交的循环,如样例1给的
(2,1,4,3) 变成置换之后为(1,2)(3,4)
**3.循环乘法之间的运算:- 对于循环里面的元素为奇数个时,(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的循环分裂得到,同时会得到另一个大小也为n的循环(这是无解的判断);也可以从上面的例子看出偶数循环分裂的规律;即奇偶分裂;
- 编码:先使用循环分解算法将对应关系转换为若干个不相交的循环,使用vector存储,为了方面读取每个循环的size();之后按循环大小排序,这里开始认为偶数次同等大小的循环叠加以后以为还要倍增叠加,其实是想多了;因为这里只是置换 的平方;所以直接用ans[位置] = value;(转化为题目要的东西即可);
#include<bits/stdc++.h>using namespace std;const int MAXN = 1e6+10;int B[MAXN],vis[MAXN],ans[MAXN],id[MAXN];vector<int> v[MAXN];#define pb push_backbool cmp(const vector<int> &a,const vector<int> &b){ return a.size() < b.size();}int main(){ int i,n,cnt = 0,tot = 0; cin>>n; for(i = 1;i <= n;i++) scanf("%d",B+i); for(i = 1;i <= n;i++)if(vis[i] != 1){ int tmp = i; ++cnt; do{ vis[tmp] = 1; v[cnt].pb(tmp); tmp = B[tmp]; }while(tmp != i); } sort(v+1,v+1+cnt,cmp); for(i = 1;i <= cnt;i++){ int sz = v[i].size(); if(sz & 1){ for(int k = 0;k < sz;k++) id[k*2%sz] = v[i][k]; for(int k = 0;k < sz;k++) ans[id[k]] = id[(k+1)%sz]; } else if(sz == v[i+1].size()){ for(int k = 0;k < sz;k++){ ans[v[i][k]] = v[i+1][k]; ans[v[i+1][k]] = v[i][(k+1)%sz]; } i++; } else{ return puts("-1"),0; } } for(i = 1;i <= n;i++){ printf("%d ",ans[i]); }}
- -
- Codeforces 612 E Square Root of Permutation
- Codeforces 612E - Square Root of Permutation
- Codeforces 612E Square Root of Permutation 【置换群】
- CodeForces 612e Square Root of Permutation(置换+构造)
- 【CF#612E】Square Root of Permutation 置换群
- Educational Codeforces Round 4 E. Square Root of Permutation(置换、构造)
- codeforces E Square Table
- Codeforces 417E Square Table(随机算法)
- Codeforces 432E Square Tiling(构造+贪心)
- Codeforces 417E Square Table(随机算法)
- codeforces 432E Square Tiling 贪心
- codeforces 432E Square Tiling(构造)
- codeforces 785E. Anton and Permutation
- codeforces 785 E. Anton and Permutation
- CodeForces 804E. The same permutation
- CodeForces 785E Anton and Permutation 分块
- Codeforces 715A Plus and Square Root
- codeforces 715A Plus and Square Root
- 多线程运行方法
- Shell小记:lsmod
- 设置eclipse中resin的JVM参数
- Android .so相关
- autocomplete 属性在html <input autocomplete="on|off">中的使用
- Codeforces 612E - Square Root of Permutation
- 17. Letter Combinations of a Phone Number
- Android异步加载AsyncTask详解
- SNS 背后的技术: 消息流的推拉模式选择
- thinkphp 截取字符串
- 树莓派的无法USB调式
- Android 讲解:Handler
- 讲解 Spark API 最好的资料
- WPF禁止拖拽窗口到边缘自动最大化