HDU 3988 Harry Potter and the Hide Story——唯一分解定理

题意:

给定n和k,求一个最大的x,使得n! % k ^ x == 0

思路:

打出素数表,用每个素数分解n!和k,得到y和x,ans = min(ans,y/x)

对m!阶乘唯一分解可以写作:

while (m) {

                m /=prime[i];

                y += m;

            }

类似于统计m以内有多少个prime[i]的倍数


#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn = 1e7 + 10;
const ll INF = 1e18;
bool isprime[maxn];
int pcnt, prime[maxn];
void creat_prime() {
    memset(isprime, true, sizeof(isprime));
    isprime[0] = isprime[1] = false;
    pcnt = 0;
    for (int i = 2; i < maxn; i++) {
        if (isprime[i]) prime[++pcnt] = i;
        for (int j = 1; j <= pcnt && prime[j] * i < maxn; j++) {
            isprime[prime[j]*i] = false;
        }
    }
}
int main() {
    creat_prime();
    int T;
    ll k, n;
    scanf("%d", &T);
    for (int kase = 1; kase <= T; kase++) {
        scanf("%lld%lld", &n, &k);
        printf("Case %d: ", kase);
        if (k == 1) {
            printf("inf\n");
            continue;
        }
        ll ans = INF;
        for (int i = 1; i <= pcnt; i++) {
            if (prime[i] > k) break;
            ll x = 0, y = 0, m = n;
            while (k % prime[i] == 0) {
                x++;
                k /= prime[i];
            }
            if (!x) continue;
            while (m) {
                m /= prime[i];
                y += m;
            }
            ans = min(ans, y / x);
        }
        if (k > 1) {
            ll y = 0, m = n;
            while (m) {
                m /= k;
                y += m;
            }
            ans = min(ans, y);
        }
        printf("%lld\n", ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/hao_zong_yin/article/details/80279702