阶乘

题目大意

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

对于 100 % 100\% 100% 的数据, n < = 100000 , a i < = 100000 n<=100000,a_i<=100000 n<=100000ai<=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=a1p1a2p2a3p3  ...,其中 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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值