[jzoj5791]【NOIP2008模拟】阶乘 (数学)

[jzoj5791]【NOIP2008模拟】阶乘 (数学)

传送门

Description

有n个正整数a[i],设它们乘积为p,你可以给p乘上一个正整数q,使p*q刚好为正整数m的阶乘,求m的最小值。

Input

共两行。
第一行一个正整数n。
第二行n个正整数a[i]。

Output

共一行
一个正整数m。

Sample Input

1
6

Sample Output

3

样例解释:
当p=6,q=1时,p*q=3!

Data Constraint

对于10%的数据,n<=10
对于30%的数据,n<=1000
对于100%的数据,n<=100000,a[i]<=100000

Code

//By Menteur_Hxy
#pragma GCC diagnostic error "-std=c++11"
#pragma GCC optimize("-fdelete-null-pointer-checks,inline-functions-called-once,-funsafe-loop-optimizations,-fexpensive-optimizations,-foptimize-sibling-calls,-ftree-switch-conversion,-finline-small-functions,inline-small-functions,-frerun-cse-after-loop,-fhoist-adjacent-loads,-findirect-inlining,-freorder-functions,no-stack-protector,-fpartial-inlining,-fsched-interblock,-fcse-follow-jumps,-fcse-skip-blocks,-falign-functions,-fstrict-overflow,-fstrict-aliasing,-fschedule-insns2,-ftree-tail-merge,inline-functions,-fschedule-insns,-freorder-blocks,-fwhole-program,-funroll-loops,-fthread-jumps,-fcrossjumping,-fcaller-saves,-fdevirtualize,-falign-labels,-falign-loops,-falign-jumps,unroll-loops,-fsched-spec,-ffast-math,Ofast,inline,-fgcse,-fgcse-lm,-fipa-sra,-ftree-pre,-ftree-vrp,-fpeephole2",3)
#pragma GCC target("avx","sse2")
#include<set>
#include<map>
#include<cmath>
#include<cstdio>
#include<vector>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define int long long
#define F(i,a,b) for(register int i=(a);i<=(b);i++)
#define R(i,a,b) for(register int i=(b);i>=(a);i--)
#define E(i,u) for(register int i=head[u];i;i=nxt[i])
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin)),p1==p2?EOF:*p1++)
using namespace std;
typedef long long LL;

char buf[1<<21],*p1,*p2;
inline int read() {
    int x=0,f=1; char c=getchar();
    while(!isdigit(c)) {if(c=='-')f=-f;c=getchar();}
    while(isdigit(c)) x=(x<<1)+(x<<3)+c-48,c=getchar();
    return x*f;
}

const int N=100010;
int n,tot,cnt;
int pri[N],vis[N],mip[N],p[N],M[N];

void resolve(int x) {
    while(mip[x]!=x) {
        if(!M[mip[x]]) p[++cnt]=mip[x];
        M[mip[x]]++; x/=mip[x];
    }
    if(mip[x]==x&&x!=1&&x!=0) {
        if(!M[mip[x]]) p[++cnt]=mip[x];
        M[mip[x]]++;
    }
}

bool jud(int x) {
    F(i,1,cnt) {
        int res=0,tmp=p[i];
        while(tmp<=x) res+=x/tmp,tmp*=p[i];
        if(res<M[p[i]]) return 0;
    } return 1;
} 

void init() {
    mip[1]=1;
    F(i,2,100000) {
        if(!vis[i]) pri[++tot]=i,mip[i]=i;
        for(register int j=1;j<=tot&&i*pri[j]<=100000;j++) {
            vis[i*pri[j]]=1; 
            mip[i*pri[j]]=pri[j];
            if(i%pri[j]==0) break;
        }
    }
}

signed main() {
    freopen("factorial.in","r",stdin);
    freopen("factorial.out","w",stdout);
    n=read();
    init();
    F(i,1,n) resolve(read());
//  jud(10);
//  F(i,1,cnt) cout<<p[i]<<" ";cout<<endl;
    int l=1,r=5e6;
    while(l<=r) {
        int mid=(l+r)>>1;
        if(jud(mid)) r=mid-1;
        else l=mid+1;
//      printf("%d\n",mid);
    }
    printf("%d",l);
    return 0;
}
posted @ 2018-08-10 20:40 Menteur_Hxy 阅读( ...) 评论( ...) 编辑 收藏
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值