CF#538 C - Trailing Loves (or L'oeufs?) /// 分解质因数

题目大意:

求n!在b进制下末尾有多少个0

https://blog.csdn.net/qq_40679299/article/details/81167283

一个数在十进制下末尾0的个数取决于10的幂的个数 即 1500=15*10^2 与两个0

在任意进制下也是 即n!在b进制下 n!=a*b^x 那么末尾0的个数就是 x

若b能分解出质因数 b1 b2 b3 ...

那么 a*b^x = a*(b1^x1 * b2^x2 * b3^x3 ... )^x = a*(b1^(x1*x) * b2^(x2*x) * b3^(x3*x) ... )

(x1表示能在b中分解出x1个b1...)

又可化成 A1*(b1^(x1*x)) 或A2*(b2^(x2*x))或 A3*(b3^(x3*x))的形式 即 A*B^X

对于特定的B 通过getcnt()可以求X 对于b1可求得X1 那么x=X1/x1

A的可能值有很多如A1 A2 A2 使得 n!=A*B^X解得的X也有多种

要使它们最终都满足 那么x应该是 X1/x1 X2/x2 X3/x3 ... 中最小的一个

#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define LL long long
#define mem(i,j) memset(i,j,sizeof(i))
const int mod=1e9+7;
const LL maxn=1e18+5;
const LL maxm=1e12+5;
LL n, b;
LL pri[10005], ind=0;
LL cnt[10005];
void get_pri(LL n) {
    mem(pri,0); mem(cnt,0);
    for(LL i=2;i*i<=n;i++) {
        while(n%i==0)
            pri[ind]=i, cnt[ind]++, n=n/i;
        if(cnt[ind]) ind++;
    }
    if(n>1) pri[ind]=n, cnt[ind++]=1;
} // 分解质因数
LL getcnt(LL p,LL n){
    LL res=0;
    while(n) res+=n/p, n/=p;
    return res;
} // n!能分解出res个p
int main()
{
    while(~scanf("%I64d%I64d",&n,&b)) {
        ind=0; get_pri(b); //printf("%d\n",ind);
        LL ans=maxn;
        for(LL i=0;i<ind;i++)
            ans=min(ans,getcnt(pri[i],n)/cnt[i]);
        printf("%I64d\n",ans);
    }

    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/zquzjx/p/10360784.html