您的位置:首页 > 其它

jzoj3775 [NOIP2014模拟8.15]因子的排列

2018-02-02 20:13 288 查看

Description

一天,小B学习了分解质因数的相关内容。他发现,一个数的质因子可以有许多不同的排列方式,例如20=2*2*5=2*5*2=5*2*2,那么小B认为20的质因子有3种不同的排列方式。小B的同学现在有一个问题:如果一个整数的质因子的不同的排列方式的种类数为k,那么这个整数n(n>1)最小是多少?小B的同学一共有T个不同的k值,希望小B帮助这个同学解决问题。但是小B发现T太大了,并且给出的k值也相当大,因此小B向你求助。

对于30%的数据,1

Solution

手玩样例可发现就是一个重复元素排列问题,答案一定是p1k1p2k2..pnknp1k1p2k2..pnkn这样的,贪心地想让k最大的p最小

感受到这样符合答案的数并不会很多,试着打了个粗略的表发现两万多一点。那么爆搜一遍用map记录一下随便出解

考场上想到了的坑:longlong会爆,得用unsignedlonglong。输入输出求稳打了cincout

然鹅还是太年轻,一个技巧就是强制转成longdouble判断是否越界再转回来。阶乘相除是可以边乘边除的,这样较大概率不会爆

Code

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <set>
#include <map>
#define rep(i,st,ed) for (int i=st;i<=ed;++i)
#define drp(i,st,ed) for (int i=st;i>=ed;--i)

typedef long long LL;
typedef unsigned long long ULL;
typedef long double LD;
const LD EPS=0.1;
const LD LIM=9223372036854775808;
const int M=2005;

ULL prime[M]={0,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53};
std:: map<ULL, ULL> map;
int rec[M];

bool get(ULL &ss,ULL &nn,ULL j,int now,ULL dep) {
rep(i,1,j) {
LD tmp1=ss,tmp2=i+dep,tmp3=i;
if (tmp1/tmp3*tmp2-LIM>EPS) return false;
if ((LD)((LD)nn*(LD)prime[now])-LIM>=EPS) return false;
ss=(ULL)(tmp1*tmp2/tmp3);
nn=nn*prime[now];
}
return true;
}

void dfs1(ULL dep,ULL s,ULL last,int now,ULL n) {
if (dep>62) return ;
if (map.count(s)==0)
map[s]=n;
else map[s]=std:: min(map[s],n);
drp(j,last,1) {
ULL ss=s,nn=n;
bool flag=get(ss,nn,j,now,dep);
if (flag) {
rec[now]=j;
dfs1(dep+(ULL)j,ss,j,now+1,nn);
rec[now]=0;
}
}
}

int main(void) {
dfs1(0,1,63,1,1);
int T; scanf("%d",&T);
while (T--) {
ULL x; scanf("%llu",&x);
if (x==1) printf("2\n");
else printf("%llu\n",map[x]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: