/*
【质因子】【快速求n!的质因子】【牛客竞赛】【阶乘】
思路:暴力最多65!=0
p如果是1111111 就直接爆了
显然是不行的
求p的质因子和指数
二分查[1,1e9]
找到里面最小且包含p的质因子和指数 n!
check()如何判断呢? 就是将n的阶层
5! 5*4*3*2*1=120
质因子就是:1*2^3*3*5
tip:质因子 对某一个数进行整除 从1 开始 分到最小的质数
24= 2*2*2*3
如果n!的质因子>=p的质因子
重要结论:对于一个正整数n来说,如果它存在[2,n]范围内的质因子
1、要么这些质因子全部小于等于sqrt(n)
2、要么只存在一个大于sqrt(n)的质因子,其余因子全部小于等于sqrt(n)
时间复杂度O(sqrt(n))
总时间复杂度O(T(sqrt(n)+logn^2))
*/
#include<iostream>
#include<cmath>
using namespace std;
struct Node{
int x;
int cnt;//cot 改成cnt
}nums[32];
int ans;
void find_p(int p)//计算p 的质因子个数
{
int pp=p;
for(int i=2;i<=sqrt(p);i++)
{
if(pp%i==0)
{
nums[ans]={i,0};
while(pp%i==0)
{
nums[ans].cnt++;
pp/=i;
}
ans++;
}
}
if(pp>1)
nums[ans++]={pp,1};
return;
}
// int check(int num,int q)//判断num!中有多少个质因子q
// {
// int number=0;
// for(int i=2;i<=num;i++)
// {
// int temp=i;
// while(temp%q==0)
// {
// number+=temp;
// temp/=q;
// }
// }
// return number;
// }//这种方式 对于数量很多的 或者 数值很大的1e18这种 就会爆
int check(int n,int q)//进阶版 时间复杂度O(logn)
{
int number=0;
while(n)
{
number+=n/q;
n=n/q;
}
return number;
}//ohhhhhhhhh~~~~ 过了!!!
int main()
{
int T,p;scanf("%d",&T);
while(T--)
{
scanf("%d",&p);
ans=0;
find_p(p);
int l=1,r=1000000000,f=1;
while(l<r)
{
int mid=(l+r)>>1;//向下取值 单调
f=1;
for(int i=0;i<ans;i++)
{
if(check(mid,nums[i].x)<nums[i].cnt)
f=0;
}
if(f)
r=mid;
else
l=mid+1;
}
printf("%d\n",l);
}
return 0;
}
【题解】牛客月赛23--B阶乘
最新推荐文章于 2024-05-29 17:10:47 发布