【质因数分解】SAC E#1 一道中档题 Factorial

SAC E#1 一道中档题 Factorial

思路:一个数x在y进制下末尾有多少零, 就是在十进制下能被y连续整除的次数

首先分解k进制,然后对于每个质因数,求出n!里有多少个质因数,然后如果k里有x个这个质因数,则求出的结果除以x。最后的答案为这些结果的最小值

如何求n!里有多少个k分解出来的质因数

代码QAQ

#include<cstdio>
#include<iostream>
#define ll long long
using namespace std;
const ll sz = 1e7, inf = 1e18;
ll n, k, cnt = 0, num = 0, ans = inf;
ll pri[sz], jz[sz], book[sz];
bool pd[sz];
void getlist() {//没问题 
    ll up = min(max(n, k), sz);
    pd[1] = pd[0] = 1;
    for(ll i = 2; i <= up; i++) {
        if(!pd[i]) pri[++cnt] = i;
        for(ll j = 1; j <= cnt && pri[j] * i <= up; j++) {
            pd[i * pri[j]] = 1;
            if(i % pri[j] == 0) break;
        }
    }
}
void resolvek(ll x) {//没问题 
    for(ll i = 1; i <= cnt; i++) {
        if(x == 1 || pri[i] > n) break;
        if(x % pri[i] == 0) {
            jz[++num] = pri[i];
            while(x % pri[i] == 0) { //这里参考的题解!tql!!! 
                x /= pri[i];
                book[num]++;
            }
        }
    }
}
int main() {
    scanf("%lld%lld", &n, &k);
    getlist();
    resolvek(k);
    for(ll i = 1; i <= num; i++) {
        ll t = n, sum = 0;
        while(t) {
            t /= jz[i];
            sum += t;
        } 
        ans = min(ans, (ll)sum/book[i]);
    }
//    if(ans == inf) printf("0");
    printf("%lld", ans);
    return 0;
}

inf 要定义的大一点 刚开始inf = 1<<30 ans 比inf要大, 这就十分gg了

原文地址:https://www.cnblogs.com/Hwjia/p/9888277.html