题目大意
有 n n n 个正整数 a i a_i ai,设它们乘积为 p p p,你可以给 p p p 乘上一个正整数 q q q,使 p ∗ q p*q p∗q 刚好为正整数 m m m 的阶乘,求 m m m 的最小值。
对于 100 % 100\% 100% 的数据, n < = 100000 , a i < = 100000 n<=100000,a_i<=100000 n<=100000,ai<=100000。
解题思路
根据题目可得,根据整数的唯一分解式, m = a 1 p 1 ∗ a 2 p 2 ∗ a 3 p 3 . . . m=a_1^{p_1}*a_2^{p_2}*a_3^{p_3} \ \ ... m=a1p1∗a2p2∗a3p3 ...,其中 a i a_i ai 为质数。
方法一
根据上式, p p p 也可以分解,那么最小的 m m m 只需满足包含所有 a i p i a_i^{p_i} aipi 就行了。
看一个数 x x x 中有多少的 t t t 的方法。
f ( x , t ) = ⌊ x t ⌋ + ⌊ x t 2 ⌋ + ⌊ x t 3 ⌋ + . . . f(x,t)=\left\lfloor\dfrac{x}{t}\right\rfloor + \left\lfloor\dfrac{x}{t^2}\right\rfloor + \left\lfloor\dfrac{x}{t^3}\right\rfloor + \ ... f(x,t)=⌊tx⌋+⌊t2x⌋+⌊t3x⌋+ ...
加到有 0 0 0 为止就行了。
采用二分答案,二分 m m m,使 m m m 满足上面的要求。
时间复杂度为 O ( 求 所 有 因 子 + n log n ) O(求所有因子 + n \log n) O(求所有因子+nlogn)
AC CODE
方法一
#include<bits/stdc++.h>
using namespace std;
#define int long long
int read()
{
int x = 0, f = 1;
char c = getchar();
while(c < '0' || c > '9')
{
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9')
{
x = x * 10 + c - 48;
c = getchar();
}
return x * f;
}
int n;
int mmax;
int ans = 0;
int a[100005];
void kkk(int x)
{
int xx = x;
for(int i = 2; i * i <= xx; ++i)
{
if(xx % i == 0)
{
while(x % i == 0)
{
x /= i;
a[i]++;
}
}
}
if(x) a[x]++;
}
int wjy(int x, int y)
{
int j = y;
int res = 0;
while(x >= j)
{
res += x / j;
j = j * y;
}
return res;
}
bool check(int mid)
{
for(int i = 2; i <= mmax; ++i)
if(wjy(mid, i) < a[i]) return false;
return true;
}
signed main()
{
n = read();
for(int i = 1; i <= n; ++i)
{
int x;
x = read();
kkk(x);
mmax = max(mmax, x);
}
int l = 1, r = 1e9;
while(l <= r)
{
int mid = (l + r) >> 1;
if(check(mid))
{
ans = mid;
r = mid - 1;
}
else
{
l = mid + 1;
}
}
printf("%lld\n", ans);
return 0;
}