Description:
给出n和b,问n!在b进制下末尾有多少个相连的0,比如6!(10)=720(10)=880(9). 所以6!在9进制下有1个0
Input:
n,b
Output:
answer
Analysis:
实际上是求n!的因数中有b^k,k的最大值为多少。可以用唯一分解定理,同时分解为质数然后判断,可以先对b进行质因数分解,然后求n对于每个b的质因数的次数,假设要求n!中质因数s的次数为多少,这里可以直接使用cnt=[n/s]+[n/s^2]+[n/s^3]+...
这样分别算的是1到n中s,s^2,s^3这些因数对答案的贡献。最后只要对n和b的相应质因数次数进行比较跟新答案即可
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<sstream>
#include<cmath>
#include<iterator>
#include<bitset>
#include<stdio.h>
#include<unordered_set>
#include<ctime>
#include<cstring>
using namespace std;
#define _for(i,a,b) for(int i=(a);i<(b);++i)
#define _rep(i,a,b) for(int i=(a);i<=(b);++i)
typedef long long LL;
const int INF = 1 << 30;
const int maxn = 1e6+5;
const int MOD = 1e9+7;
const double eps = 1e-6;
LL n, b;
map<LL,LL> b_;
map<LL,LL> n_;
int main()
{
//freopen("C:\\Users\\admin\\Desktop\\in.txt", "r", stdin);
//freopen("C:\\Users\\admin\\Desktop\\out.txt", "w", stdout);
while (cin >> n >> b) {
LL bb = b;
b_.clear(); n_.clear();
LL can = sqrt(b) + 1;//所有质数的范围
for (LL i = 2; i < can; ++i)//遍历
{
LL cnt = 0;
while (b%i == 0)//对于每个可以约去的数字
{
cnt++;
b = b / i;//相除
}
if (cnt > 0) b_[i] = cnt;
}
if(b!=1) b_[b] = 1;
LL ans = 0x3f3f3f3f3f3f3f3fLL;
for (auto it : b_) {
LL cnt = 0, tmp = it.first;
LL nn = n;
while (nn) { cnt+=nn/tmp; nn/= it.first; }
n_[it.first] = cnt;
ans = min(ans, n_[it.first] / b_[it.first]);
}
cout <<ans<<endl;
}
return 0;
}