1174.阶乘
时间限制:1000MS内存限制:256000KB
题目描述
有n个正整数a[i],设它们乘积为p,你可以给p乘上一个正整数q,使p*q刚好为正整数m的阶乘,求m的最小值。
输入
共两行。
第一行一个正整数n。
第二行n个正整数a[i]。
输出
共一行
一个正整数m。
输入样例复制
1
6
输出样例复制
3
说明
样例解释: 当p=6,q=1时,p*q=3! Data Constraint 对于10%的数据,n<=10 对于30%的数据,n<=1000 对于100%的数据,n<=100000,a[i]<=100000
题解:可以把p分解质因数,假设p=∏ai^bi(ai为质数),那么只要m!包含了每个ai^bi,m!就包含p。
所以对于每个ai^bi,分别求出满足条件的最小的m,取最大值即可。
怎么求m?
先看一个简单的问题:
27!里面有多少个3相乘?
27!=1*2*...*27
包含1个3的数有27/(3^1)=9个
包含2个3的数有27/(3^2)=3个
包含3个3的数有27/(3^3)=1个
总共:9+3+1=13个
所以27!里面有13个3相乘。
用这个方法就可以求得m!有多少个ai相乘,二分判断即可。
var
m,pm,num,l,r,ans,i,n,j:longint;
a,t,b,p:array[0..10000000]of longint;
f:array[0..10000000]of boolean;
procedure sushu(x:longint);
var
i,j:longint;
begin
i:=1;
f[0]:=false;
f[1]:=false;
for i:=2 to x do
begin
if f[i]=true
then begin
inc(num);
p[num]:=i;
b[i]:=i;
end;
for j:=1 to num do
begin
f[p[j]*i]:=false;
b[p[j]*i]:=b[i];
if i mod p[j]=0 then break;
if i*p[j+1]>x then break;
end;
end;
end;
procedure add(x:longint);
begin
while x>1 do
begin
if(b[x]>pm) then pm:=b[x];
inc(t[b[x]]);
//writeln(b[x]);
x:=x div b[x];
end;
end;
function check(x:longint):boolean;
var
i:longint;
j,s:int64;
begin
for i:=1 to pm do
begin
if f[i]=false then continue;
j:=i;
s:=0;
while(j<=x) do
begin
s:=s+(x div j);
j:=j*i;
if s>=t[i] then break;
end;
if s<t[i] then exit(false);
end;
exit(true);
end;
procedure init;
begin
for i:=1 to n do
begin
read(a[i]);
add(a[i]);
end;
end;
begin
//assign(input,'1.in');reset(input);
readln(n);
fillchar(f,sizeof(f),true);
sushu(1000000);
init;
l:=pm;r:=1000000000;
while(l<r) do
begin
m:=(l+r)div 2;
if check(m) then r:=m
else l:=m+1;
end;
writeln(l);
//close(input);
end.