【JZOJ A组】排列
Description
一个关于n个元素的排列是指一个从{1, 2, …, n}到{1, 2, …, n}的一一映射的函数。这个排列p的秩是指最小的k,使得对于所有的i = 1, 2, …, n,都有p(p(…p(i)…)) = i(其中,p一共出现了k次)。
例如,对于一个三个元素的排列p(1) = 3, p(2) = 2, p(3) = 1,它的秩是2,因为p(p(1)) = 1, p(p(2)) = 2, p(p(3)) = 3。
给定一个n,我们希望从n!个排列中,找出一个拥有最大秩的排列。例如,对于n=5,它能达到最大秩为6,这个排列是p(1) = 4, p(2) = 5, p(3) = 2, p(4) = 1, p(5) = 3。
当我们有多个排列能得到这个最大的秩的时候,我们希望你求出字典序最小的那个排列。对于n个元素的排列,排列p的字典序比排列r小的意思是:存在一个整数i,使得对于所有j < i,都有p(j) = r(j),同时p(i) < r(i)。对于5来说,秩最大而且字典序最小的排列为:p(1) = 2, p(2) = 1, p(3) = 4, p(4) = 5, p(5) = 3。
Input
输入的第一行是一个整数T(T <= 10),代表数据的个数。
每个数据只有一行,为一个整数N。
Output
对于每个N,输出秩最大且字典序最小的那个排列。即输出p(1), p(2),…,p(n)的值,用空格分隔。
Sample Input
2
5
14
Sample Output
2 1 4 5 3
2 3 1 5 6 7 4 9 10 11 12 13 14 8
Data Constraint
对于40%的数据,有1≤N≤100。
对于所有的数据,有1≤N≤10000。
思路
显然,我们肯定是把它拆成形如p1x1,p2x2,p3x3……大小的环(p是质数)
原因:可以发现,这些数最总经过若干次后便会自己其实就是一直在走环(可能走多次),一周期就是还的大小,那么多个周期的共同周期就是它们的lcm,所以我们应该让所有数互质。
我们可以用DP解决这个问题:f[i][j]为前i个质数,和为j的最大乘积。转移十分暴力,枚举质数即可(注意如果指数为0,那么就没必要占用一个位置)
我们要知道你那个乘积是怎么来的。我们只要用g数组记录一下所用质数和前驱即可
代码
#include<bits/stdc++.h>
using namespace std;#define N 10077
#define M 1377bool bz[N];
double f[M][N];
int p[M],a[N],ans[N],Q[20],g[M][N];
int T,n;void pre()
{for(int i=2; i<=n; i++){if(!bz[i]){bz[i]=1;p[++p[0]]=i;}for(int j=1; j<=p[0]; j++){if(i*p[j]>n) break;bz[i*p[j]]=1;if(i%p[j]==0) break;}}
}void dp()
{for(int i=0; i<p[0]; i++){for(int j=0; j<=n; j++){if(f[i][j]>f[i+1][j]){f[i+1][j]=f[i][j];g[i+1][j]=j;}int k=p[i+1];double del=log(p[i+1]),t=del;for(; k+j<=n; k*=p[i+1],t+=del){if(f[i][j]+t>=f[i+1][j+k]){f[i+1][j+k]=f[i][j]+t;g[i+1][j+k]=j;}}}}
}void solve()
{double mx=0;int now=n;a[0]=0;for(int i=1; i<=n; i++)if(f[p[0]][i]>mx){mx=f[p[0]][i];now=i;}for(int i=1; i<=n-now; i++) a[++a[0]]=1;int i=p[0];while(i){a[++a[0]]=now-g[i][now];now=g[i][now];i--;}
}void find()
{sort(a+1,a+a[0]+1);int w=0,k=1;while(!a[k]&&k<=p[0]) k++;for(int i=1; i<=n; i++){if(i==w+a[k]){ans[i]=w+1;w+=a[k];k++;}else ans[i]=i+1;}
}void print()
{for(int i=1; i<n; i++) printf("%d ",ans[i]);printf("%d\n",ans[n]);
}int main()
{scanf("%d",&T);memset(f,0,sizeof(f));memset(g,0,sizeof(g));for(int i=1; i<=T; i++){scanf("%d",&Q[i]);n=max(n,Q[i]);}pre();dp();for(int i=1; i<=T; i++){n=Q[i];solve();find();print();}return 0;
}
【JZOJ A组】排列相关推荐
- jzoj C组 2017.1.19 比赛
第一题--小x的游戏 题目描述 Tac游戏在一个4*4的方格上进行.起先可能会在16个方格中出现一个标记'T',其余的方格是空着的.游戏有两个玩家,小x和小o.小x先开始,然后游戏轮流进行.每一步玩家 ...
- 【JZOJ B组】【NOIP2013模拟9.29】密码
Description 在又一次消灭林登·万的战斗中,指挥官moreD缴获了一个神奇的盒子.盒子异常的坚固,以至于完全无法摧毁,唯一打开的方式是通过盒上的密码锁. 经过仔细的调查,研究人员一致认为这个 ...
- 【JZOJ A组】海明距离
Description 对于二进制串a,b,他们之间的海明距离是指两个串异或之后串中1的个数.异或的规则为: 0 XOR 0 = 0 1 XOR 0 = 1 0 XOR 1 = 1 1 XOR 1 = ...
- 【JZOJ A组】昆特牌
Description 作为一个资深OIer,你被邀请到位于波兰的CDPR总部参观.但没想到你刚一到就遇到了麻烦.昆特牌的数据库发生了故障.原本昆特牌中有 k种卡牌和n 种阵营,为了平衡,每个阵营拥有 ...
- 【JZOJ A组】黑暗之魂(darksoul)
Description oi_juruo热爱一款名叫黑暗之魂的游戏.在这个游戏中玩家要操纵一名有 点生命值的无火的余灰在一张地图中探险.地图中有n个篝火(也就是存档点).在篝火处休息可以将生命值恢复满 ...
- 【JZOJ B组】【JSOI2013】吃货JYY
Description 世界上一共有N个JYY愿意去的城市,分别从1编号到N.JYY选出了K个他一定要乘坐的航班.除此之外,还有M个JYY没有特别的偏好,可以乘坐也可以不乘坐的航班. 一个航班我们用一 ...
- 【JZOJ A组省选】词典
Description Input 第一行两个数n,m,表示有n个字符串,m个询问. 接下来n行,每行一个字符串Ti . 再接下来m行,每行一个字符串Si . Output 对于每个询问,输出一个an ...
- JZOJ B组【GDKOI2014】壕壕的寒假作业
题目: Input Output 输出n行.第i行输出两个整数,分别表示第i份作业最早完成的时刻以及最晚完成的时刻,两个整数之间以一个空格间隔. Sample Input 4 4 3 4 5 6 1 ...
- 【JZOJ B组】【NOIP2013模拟】小喵喵的新家
Description 小喵喵和小聪聪从小就是好朋友 ,他们经常在一起玩耍 .如今小喵已经厌倦了自己居住的环境,想请小聪聪为她建一个新家. 小喵喵天生多才多艺,对多种乐器颇有研究.对于生活中常见的图形 ...
最新文章
- linux入门之目录结构
- Bete冲刺第五阶段
- Linux Used内存到底哪里去了?
- linux weblogic修改内存,在linux运行weblogic出现运行内存不足错误,求鞭挞....
- idea js检查太卡_IntelliJ IDEA抑制、禁用与启用检查
- Win7电脑开启局域网连接和共享过程中出现的您可能没有权限使用网络资源的解决办法...
- python求解最大子序列问题,子序列可连续或不连续
- 《跨越鸿沟》中的提到的五类用户
- 【亲测】CMD中文乱码终极解决方案
- 成都电子信息学校计算机专业,成都电子信息学校2020招生简章
- 读《采购与供应链管理》
- php保存pdf旋转90度,如何将PDF图片旋转90度,盘点这个小方法
- 怎样修复win10计算机系统,几种常见修复win10系统情况及修复方法介绍
- 推流是什么,直播为什么要推流
- 网络知识:快速了解IP地址的概念以及IPV4和IPV6的区别!
- 混迹在腾讯微博的知名站长名单(截至4月28日)
- 计算机辅助设计职业标准,计算机辅助设计绘图员国家职业标准..doc
- 生化危机6pc测试软件,《生化危机6》PC性能测试 移植作一贯不忍直视
- javaweb基于JSP开发Java在线学习平台 大作业 毕业设计源码
- [野狐行网游研究][一期][8.17更新]