题解:ABC280D - Factorial and Multiple

题解:ABC280D - Factorial and Multiple

·题目

链接:Atcoder。

链接:洛谷。

·难度

算法难度:B。

思维难度:A。

调码难度:A。

综合评价:普及/提高-。

·算法

质因数分解+数论。

·思路

这题真是的,纯纯考数学。

首先,如果k本身是质数输出k即可(前面乘几都没用)。

剩下的答案,先给k分解质因数,记每个质数为p[i],对应的个数为sum[i],质数数量为cnt,最差情况下答案为p[cnt]*sum[cnt],这里阶乘中至少有sum[cnt]个p[cnt]的倍数,自然满足要求。于是我们先从1枚举到根号k,如果之中没有合法的情况就输出最差情况下的答案。

·代价

O(sqrt(k))。

·细节

判断是否合法,可以用sumot[i]记录当前的阶乘中能够整除p[i]的多少幂次。

最后判断是否是每个sum[i]都<=sumot[i]即可。

·代码

#include
#define S 1100000
using namespace std;
long long p[S]={},sum[S]={},sumot[S]={},cnt=0,k=0;
bool prime(long long num);
void resolve(long long num);
int main(){
    scanf("%lld",&k);
    if(prime(k)==true){
        printf("%lld\n",k);
        return 0;
    }
    resolve(k);
    for(long long i=1;i*i<=k;i++){
        long long tmp=i;
        bool flag=false;
        for(long long j=1;j<=cnt;j++){
            while(tmp%p[j]==0){
                tmp/=p[j];
                sumot[j]++;
            }
            if(sum[j]>sumot[j]){
                flag=true;
            }
        }
        if(flag==false){
            printf("%lld\n",i);
            return 0;
        }
    }
    long long ans=p[cnt]*sum[cnt];
    printf("%lld\n",ans);
    return 0;
}
bool prime(long long num){
    for(long long i=2;i*i<=num;i++){
        if(num%i==0){
            return false;
        }
    }
    return true;
}
void resolve(long long num){
    long long tmp=num;
    for(long long i=2;i*i<=num;i++){
        if(tmp%i==0){
            cnt++;
            p[cnt]=i;
        }
        while(tmp%i==0){
            tmp/=i;
            sum[cnt]++;
        }
    }
    if(tmp>1){
        if(p[cnt]==tmp){
            sum[cnt]++;
        }else{
            cnt++;
            p[cnt]=tmp;
            sum[cnt]++;
        }
    }
    return;
}

·注意

分解质因数时一定特殊判断那个>sqrt(num)的数。

你可能感兴趣的:(算法,math)