jzoj3775 因子的排列

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]);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值