DTOJ3084 置换permutation
DTOJ3084 置换permutation
- 题目
- 题目描述
- 输入格式
- 输出格式
- 样例
- 样例输入
- 样例输出
- 数据范围与提示
- 题解
题目
题目描述
定义一个置换PPP的平方QQQ为对[1,2,3,⋯⋯,n−1,n][1,2,3,\cdots \cdots,n -1,n][1,2,3,⋯⋯,n−1,n]做两次该置换得到的排列,即Qi=PpiQ_i=P_{p_i}Qi=Ppi
现在已知一个置换的平方,求该置换
输入格式
第一行一个整数nnn表示排列长度
第二行nnn个整数表示所求置换的平方
输出格式
若有解则输出一行nnn个数表示原置换(输出任意一个),否则输出−1-1−1
样例
样例输入
4
2 1 4 3
样例输出
3 4 2 1
数据范围与提示
20%20\%20%的数据:n⩽10n\leqslant 10n⩽10
100%100\%100%的数据:1⩽n⩽1061\leqslant n\leqslant 10^61⩽n⩽106
题解
我们先来观察一下置换平方后是什么鬼
假设我们有一个置换:(2,3,1,5,4)(2,3,1,5,4)(2,3,1,5,4)
它可以被拆解为两个环:[2,3,1][5,4][2,3,1][5,4][2,3,1][5,4]
我们把它平方一下:(3,1,2,4,5)(3,1,2,4,5)(3,1,2,4,5)
发现它可以拆成三个环:[3,1,2][4][5][3,1,2][4][5][3,1,2][4][5]
我们发现,如果是一个偶环,平方后就拆开了,如果是一个奇环,就还会是一个奇环
得到了这个规律以后,我们就可以处理这道题了
先把平方后的结果拆成环,对于偶环,就两两合并,比如[1,3,5][1,3,5][1,3,5]和[2,4,6][2,4,6][2,4,6]合并为[1,2,3,4,5,6][1,2,3,4,5,6][1,2,3,4,5,6];对于奇环,通过观察,可以发现,我们需要把它拆成两半之后合并,比如[1,3,2][1,3,2][1,3,2]拆成[2,1][3][2,1][3][2,1][3]合并为[2,3,1][2,3,1][2,3,1](注意,这里的环指的并不是按照置换中的顺序排的,而是按遍历的顺序)
最后,对于输出−1-1−1的情况当然只有一个啦,那就是有奇数个偶环
附上代码:
#include<cstring>
#include<cstdio>
#include<vector>
using namespace std;
int n,Size,q[1000010],v[1000010],p[1000010];
vector<int> h[1000010],l[1000010];
int main()
{freopen("permutation.in","r",stdin);freopen("permutation.out","w",stdout);scanf("%d",&n);for(int i=1;i<=n;i++) scanf("%d",&q[i]);for(int i=1;i<=n;i++){int s=0;for(int j=i;!v[j];j=q[j]) v[j]=1,s++,h[i].push_back(j);l[s].push_back(i);}for(int i=1;i<=n;i++) if((!(i&1))&&(l[i].size()&1)){printf("-1");return 0;}memset(v,0,sizeof(v)),Size=l[1].size();for(int i=0;i<Size;i++) p[l[1][i]]=l[1][i]; for(int i=2;i<=n;i++){Size=l[i].size();for(int j=0;j<Size;j++)if(i&1){int x=h[l[i][j]][0],y=h[l[i][j]][i/2+1];while(!v[x]) v[x]=v[y]=1,p[x]=y,x=q[x],p[y]=x,y=q[y];}else{int x=h[l[i][j]][0],y=h[l[i][j+1]][0];while(!v[x]&&!v[y]) v[x]=v[y]=1,p[x]=y,x=q[x],p[y]=x,y=q[y];j++;}}for(int i=1;i<=n;i++) printf("%d ",p[i]);
}
DTOJ3084 置换permutation相关推荐
- 近世代数--置换群--置换permutation分解成什么?置换的级如何计算?
近世代数--置换群--置换permutation分解成什么?置换的级如何计算? 置换的分解 置换的级计算 博主是初学近世代数(群环域),本意是想整理一些较难理解的定理.算法,加深记忆也方便日后查找:如 ...
- 周期置换加密算法用c语言实现,古典密码实验报告.doc
. .. 哈尔滨工程大学 实 验 报 告 实 验 名 称: 古典密码算法 班 级: 学 号: 姓 名: 实 验 时 间: 2014年4月 成 绩: 指 导 教 师: 实验室名称: 哈尔滨工程大学实验室 ...
- Nature综述:Rob Knight带你分析微生物组数据(2020版)
文章目录 微生物组分析最佳实践 导读 摘要Abstract 背景介绍Introduction 实验设计Experimental design 图1. 微生物组实验设计中的注意事项 知识点1. 优秀工作 ...
- r语言 tunerf函数_R语言︱常用统计方法包 机器学习包(名称、简介)
一.一些函数包大汇总 转载于:http://www.dataguru.cn/thread-116761-1-1.html 时间上有点过期,下面的资料供大家参考 基本的R包已经实现了传统多元统计的很多功 ...
- r语言的MASS包干什么的_R语言综述的包
Multivariate Statistics (多元统计) 基本的R包已经实现了传统多元统计的很多功能,然而CRNA的许多其它包提供了更深入的多元统计方法,下面做个简要的综述.多元统计的特殊应用在C ...
- 论文阅读:A Randomly Accessible Lossless Compression Scheme for Time-Series Data
一.主题 标题上也说了,关于对时间序列数据进行压缩的一种对经典重复数据删减的改进版,并能够对压缩后的数据进行随机访问而不用解压缩: 期刊:IEEE INFOCOM 2020 A类 二.动机 目 ...
- Nature综述:Rob Knight带你分析微生物组数据
微生物组分析最佳实践 Best practices for analysing microbiomes Impact Factor:34.648 https://doi.org/10.1038/s41 ...
- 信息系统自动决策机制的使用
声明 本文是学习360 企业个人信息合规思路与实践报告 2021. 下载地址 http://github5.com/view/1273而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我 ...
- PrivacyIN Week2 | 张宇鹏博导开讲经典零知识证明协议设计原理
前言 隐私研究院[PrivacyIN]第一期ZK训练营课程精讲内容上线,本期课堂邀请到美国德州农工大学(Texas A&M University)计算机科学与工程学院的助理教授张宇鹏,主要介绍 ...
最新文章
- cannot access a closed file
- PYPL 12 月 IDE 榜单:Eclipse 有望超越 Visual Studio
- css3动画模块transform transition animation属性解释
- 为bootstrap的tab增加请求操作
- 命令行运行vbs脚本并传参数给vbs中的变量简单示例
- gulp与grunt对比
- MyLinkedList
- html5中行内样式写法,react怎么写行内样式?
- 【C语言】求s(n)=a+aa+aaa+...+aa...a的值
- Oracle总结第一篇【基本SQL操作】
- 创建前缀一样的文件_Win10更快速创建或重命名仅扩展名文件
- nagios 主机报警别名修改
- Python巨型文字游戏开发(带源码(1))
- 7个向上管理技巧,让你的职场一路开挂
- VDI(Virtual Desktop Infrastructure)
- 【机器学习开放项目】安然公司电子邮件数据集
- Java 反射 理解
- Windows Support Tools
- java kpi_JAVA内存调优的KPI
- 日记 | STM32串口显示YL-69土壤湿度
热门文章
- 在亚马逊严抓测评的风口下,亚马逊买家秀关联视频或许是一个安全有效的方式
- 阿里云服务器SSH连接自动断开问题
- 给el-input type=“number“的文本框设置默认值
- 一文读懂「用户行为数据」的采集、分析和应用
- iOS Developer:真机测试
- 建筑公司设计公司网站建设制作费用大概多少
- java面试技术准备
- 浅议网上支付系统关键技术探究
- 计算机缺少更新,Win10电脑无法更新提示你的设备中缺少重要的安全和质量修复怎么处理...
- talend缺少mysql驱动器怎么办_关于使用talend遇到的问题