Trailing Loves (or L'oeufs?)
【题解】:
题意是:给你一个n,b。然后问在b进制下,n!的末尾有多少个0.
首先我们回顾一下,在10进制下面,n的阶乘末尾零的计算方法是:
把10=2*5,
然后2为因子的个数有:n/2+n/(2^2)+n/(2^3)……
然后5为因子的个数有:n/5+n/(5^2)+n/(5^3)……
其实这个题目就是照葫芦画瓢,
把所有b的质因子分解出来,然后看看哪一个质因子最少即可。
注意注意,由于题目给的数字太大,进行 n/(s^t),这一步的时候需要把乘法变成来判断,不然会超数据范围。
贴上自己的代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=4e6+100;
const int M=1e4;
const ll inf=1e10;
ll prime[N],cnt;
ll a[M],b[M],c[M];
bool isprime[N];
void Euler(){
memset(isprime,true,sizeof(isprime));
for(ll i=2;i<N;i++){
if(isprime[i])
prime[cnt++]=i;
for(ll j=0;j<cnt&&i*prime[j]<N;j++){
isprime[i*prime[j]]=false;
if(i%prime[j]==0) break;
}
}
}
int main()
{
ll n,B,tB,tot=0;
Euler();
scanf("%lld%lld",&n,&B);
for(ll i=0;i<cnt&&1ll*prime[i]*prime[i]<=B;i++){
if(B%prime[i]==0){
a[tot]=prime[i];
while(B%prime[i]==0){
b[tot]++;
B/=prime[i];
}
tot++;
}
}
if(B!=1ll){
a[tot]=B;
b[tot]++;
tot++;
}
ll ans=0,minz=0x3f3f3f3f3f3f3f3f;
for(ll i=0;i<tot;i++){
//printf("%lld %lld\n",a[i],b[i]);
ll sum=0;
for(ll t=1;t<=n/a[i];t*=a[i]){
sum+=n/(t*a[i]);
}
minz=min(minz,sum/b[i]);
}
printf("%lld\n",minz);
return 0;
}
/*
1000000000000000000 97
1000000000000000000 1000000000000
*/
贴上官方的标程:
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
long long n, b;
void Input() {
cin >> n >> b;
}
void Solve() {
long long ans = 1000000000000000000LL;
for (long long i=2; i<=b; i++) {
if (1LL * i * i > b) i = b;
int cnt = 0;
while (b % i == 0) {b /= i; cnt++;}
if (cnt == 0) continue;
long long tmp = 0, mul = 1;
while (mul <= n / i) {mul *= i; tmp += n / mul;}
ans = min(ans, tmp / cnt);
}
cout << ans << endl;
}
int main(int argc, char* argv[]) {
ios_base::sync_with_stdio(0); cin.tie(NULL);
Input(); Solve(); return 0;
}