题目
题目描述
一天,小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向你求助。
样例输入
4
1
2
3
105
样例输出
2
6
12
720
数据范围
对于30%的数据,n<=100000
对于全部的数据,n<
263
2
63
,k<
263
2
63
,1<=T<=1000
题解
某位大佬说过,LL范围内一个数最多化为由15个不同的质因数的乘积。
所以直接暴力枚举素数的乘积。
首先,
n=p1e1∗p2e2∗…∗pmem
n
=
p
1
e
1
∗
p
2
e
2
∗
…
∗
p
m
e
m
,则
k=(Σmi=1ei)!Πmi=1(ei)!
k
=
(
Σ
i
=
1
m
e
i
)
!
Π
i
=
1
m
(
e
i
)
!
所以符合条件的n一定有
e1≥e2≥e3≥...≥em
e
1
≥
e
2
≥
e
3
≥
.
.
.
≥
e
m
。
通过暴力,求出了≤50000个合法的数。然后通过维护质因数分解的前缀和来求出各自的k,然后再排序。
但是有一种更简单的方法。
突然发现,
所以直接维护组合数就可以了。
代码
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#define N 110
#define M 45010
#define LL long long
#define P(a) putchar(a)
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fd(i,a,b) for(i=a;i>=b;i--)
using namespace std;
struct note{
LL ls,k;
};note md[M];
LL i,j,k,l,r,mid,ans;
LL n,mx,lim,up,x,cnt,w,T,m[N];
LL o[N],tar[N];
LL mi[N][N];
LL ls[M],a[N];
LL p[N],e[N];
LL sum[N][N];
bool pp;
void write(LL x){
if(x>9)write(x/10);
P(x%10+'0');
}
void dg(LL x,LL y,LL z){
LL i,j,l;
if(x>18)return;
if(z<=up)ls[ls[0]++]=z;
l=y<m[x]?y:m[x];
fd(i,l,1){
j=up/z;
if(j<mi[x][i])continue;
dg(x+1,i,z*mi[x][i]);
}
}
void gett(){
LL i,x,k;
fo(i,2,62){
x=i;p[0]=0;k=1;
while(x>1&&k*k<=i){
k++;
if(x%k==0){
p[++p[0]]=k;
e[p[0]]=0;
while(x%k==0)x/=k,e[p[0]]++;
}
}
if(x>1)p[++p[0]]=x,e[p[0]]=1;
fo(j,1,19)sum[i][j]=sum[i-1][j];
fo(j,1,p[0])sum[i][tar[p[j]]]+=e[j];
}
}
bool cmp(note x,note y){return x.k<y.k || x.k==y.k &&(x.ls<y.ls);}
int main(){
up=9223372036854775807;
o[1]=2;o[2]=3;o[3]=5;o[4]=7;o[5]=11;o[6]=13;o[7]=17;o[8]=19;
o[9]=23;o[10]=29;o[11]=31;o[12]=37;o[13]=41;o[14]=43;o[15]=47;
o[16]=53;o[17]=59;o[18]=61;
fo(i,1,18)tar[o[i]]=i;
fo(i,1,18){
lim=floor(log(1.0*up)*1.0/log(1.0*o[i]));
mx=1;mi[i][0]=1;
fo(j,1,lim)
mi[i][j]=mi[i][j-1]*o[i];
m[i]=lim;
while(mi[i][m[i]]<0)m[i]--;
}
dg(1,62,1);ls[0]--;
gett();
fo(i,1,ls[0]){
x=ls[i];p[0]=0;k=1;
while(x>1&&k*k<=ls[i]){
k++;
if(x%k==0){
p[++p[0]]=k;
e[p[0]]=0;
while(x%k==0)x/=k,e[p[0]]++;
}
}
if(x>1)p[++p[0]]=x,e[p[0]]=1;
w=0;
fo(j,1,p[0])w+=e[j];
fo(j,1,18)a[j]=sum[w][j];
fo(j,1,p[0])
fo(k,1,18)a[k]-=sum[e[j]][k];
k=1;pp=0;
fo(j,1,19)
if(a[j]>0){
l=up/k;
if(l>=mi[j][a[j]]){
k*=mi[j][a[j]];
}else{
pp=1;
break;
}
}
if(!pp){
md[++cnt].ls=ls[i];
md[cnt].k=k;
}
}
sort(md+1,md+cnt+1,cmp);
scanf("%lld",&T);
while(T--){
scanf("%lld",&x);
l=ans=1;r=cnt;
while(l<=r){
mid=(l+r)>>1;
if(md[mid].k<x)l=mid+1;
else ans=mid,r=mid-1;
}
printf("%lld\n",md[ans].ls);
}
return 0;
}