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. Nodepad ++

    Nodepad ++是一个很好用的记事本工具.轻巧.打开文本速度要比windows内置的记事本快,而且功能众多. 支持多种语言,关键字高亮显示 并且可以折叠 内置n种主题,随时换 文件内容一变随时提醒 ...

  2. Java基础知识强化100:JVM 内存模型

    一. JVM内存模型总体架构图:  方法区和堆由所有线程共享,其他区域都是线程私有的 二. JVM内存模型的结构分析: 1. 类装载器(classLoader) 类装载器,它是在java虚拟机中用途是 ...

  3. 命令行界面下用户和组管理之userdel的使用

    userdel - delete a user account and related files 在Linux中,userdel命令的功能是删除系统中的用户及相关的文件 语法    userdel ...

  4. C语言细节总结笔记

    C语言细节总结笔记 */--> C语言细节总结笔记 Table of Contents 1. 三步异或法交换数字 2. 做差法交换数字 3. 按n位置位 4. 求余求商求积 5. 辗除法求最大公 ...

  5. Ubuntu Linux---控制用户权限:root特权/sudo

    借了本<Ubuntu Linux指南>开始学学乌邦图吧,熟悉之后再下个红帽来玩玩,现在说说我们一直提到的root,但是在Linux中,这个root有所不同...大多数Linux系统都为一个 ...

  6. Oracle计算连续天数,计算连续时间,Oracle连续天数统计

    Oracle计算连续天数,计算连续时间,Oracle连续天数统计 >>>>>>>>>>>>>>>>> ...

  7. 移动平台3G手机网站前端开发布局技巧

    本文转载至:移动平台3G手机网站前端开发布局技巧汇总 - 前端开发-武方博 您或许正在或准备参与一个WepApp项目,您或许正在Google搜索mobile development相 关的文章,您或许 ...

  8. js中 this篇

    以下文案皆来自<你不知道的JavaScript 上卷>——读书笔记摘要 this 到底是什么? 排除了一些错误理解之后,我们来看看 this 到底是一种什么样的机制. 之前我们说过 thi ...

  9. 精妙SQL语句介绍

    说明:复制表(只复制结构,源表名:a 新表名:b) SQL: select * into b from a where 1<>1 说明:拷贝表(拷贝数据,源表名:a 目标表名:b) SQL ...

  10. Android沉浸式状态栏实现

    Step1:状态栏与导航栏半透明化 方法一:继承主题特定主题 在Android API 19以上可以使用****.TranslucentDecor***有关的主题,自带相应半透明效果 例如: < ...