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向你求助。
Input
第一行,一个整数T。
接下来的T行,每行一个整数k。
Output
T行,每行一个整数,其中第i行的整数表示第i个k值对应的n的值。
Sample Input
4
1
2
3
105
Sample Output
2
6
12
720
Data Constraint
对于30%的数据,1
Solution
首先,我们知道一个整数可以写成如下形式
A=(p1^a1)(p2^a2)(p3^a3)……
其中p为质数
然后排列方案书就等于(a1+a2+a3……)!/(a1!*a2!*a3!……)
为什么呢?
分母是总方案数
然后分子就是一些不合法的情况
这就相当于组合公式中除去的m!一样,是同一个道理
假设p1
Code
#include <cstdio>
#include <cstring>
#include <algorithm>
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
typedef long long ll;
typedef long double ldb;
const ldb inf=9223372036854775808.0;
int num,t,k,i,pr[16]={0,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47};
ll ans[2000];
struct edge{
ll x,y;
} h[45000],a[5000];
ll read(){
ll sum=0;
char c=getchar();
while (c<'0'||c>'9') c=getchar();
while (c>='0'&&c<='9'){
sum=sum*10+c-'0';
c=getchar();}
return sum;
}
bool cmp(edge a,edge b){return a.x<b.x||(a.x==b.x&&a.y<b.y);}
inline void dg(int x,ll y,ldb z,int u,int p){
h[++num].y=y,h[num].x=(ll)z;
ll k=1; int i;
if (x>15) return;
fo(i,1,p){
k*=pr[x],z=z*(i+u)/i;
if (y>inf/k||z>inf) break;
dg(x+1,y*k,z,u+i,i);}
}
int main(){
//freopen("1.in","r",stdin);
//freopen("1.out","w",stdout);
dg(1,1,1,0,63);
sort(h+1,h+num+1,cmp);
t=read();
fo(i,1,t) a[i].x=read(),a[i].y=i;
sort(a+1,a+t+1,cmp);
k=2;
fo(i,1,t){
while (k<=num&&a[i].x>h[k].x) k++;
ans[a[i].y]=h[k].y;
}
fo(i,1,t) printf("%lld\n",ans[i]);
}