CodeForces - 1114C Trailing Loves (or L'oeufs?)(分解质因数)
CF1114C Trailing Loves (or L'oeufs?)
题目大意:
给定\(n\),求\(n!\)在\(b\)进制下末尾\(0\)的个数。
思路:
我们以十进制来举例子。
进制数\(10 = 2 \times 5\)
比如说一个十进制数\(20\),末尾有一个\(0\),将\(20\)质因数分解为\(20 = 2^{2} \times 5\)
十进制\(100\),末尾有两个\(0\),将其质因数分解为\(100 = 2^{2} \times 5^{2}\)
十进制数\(1000\),末尾有三个\(0\),将其质因数分解为\(1000 = 2^{3} \times 5^{3}\)
……
不难发现其规律。
设进制数\(b\) \(=\) \(p_1^{r_1}\)\(\times\)\(p_2^{r_2}\)\(\times\)…\(\times\)\(p_k^{r_k}\),质数\(p_1\),\(p_2\),…,\(p_k\)在\(n!\)中的次数分别为\(cnt_1\),\(cnt_2\),…,\(cnt_k\),答案为\(min(⌊\frac{cnt_1}{p_1}⌋,⌊\frac{cnt_2}{p_2}⌋…⌊\frac{cnt_k}{p_k}⌋)\)
对于求\(n!\)中每一个质数出现的次数,我们再举一个例子。
比如\(5!\)中质数\(2\)的出现次数:
\(5 / 2 = 2\)
\(2 / 2 = 1\)
\(1 / 2 = 0\)
你会发现将等式右边的数求和正好是\(2\)的出现次数。
Formally,对于质数\(p\),其在\(n!\)中的出现次数为:\(\sum_{i=1}^{r}{\lfloor {\frac{n}{p^i}}\rfloor}(p^r \le n , p^{r+1} > n)\)
Code:
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 10010;
const LL INF = 0x3f3f3f3f3f3f3f3f;
struct Prime {
LL num, tot;
}p[N];
LL cnt;
void pff(LL x) { //分解质因数
for (LL i = 2; i * i <= x; i++) {
while (x % i == 0) {
x /= i;
if (p[cnt].num == i) p[cnt].tot++;
else p[++cnt].num = i, p[cnt].tot = 1;
}
}
if (x > 1) {
if (p[cnt].num == x) p[cnt].tot++;
else p[++cnt].num = x, p[cnt].tot = 1;
}
}
int main() {
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
LL n, b; cin >> n >> b;
pff(b);
LL ans = INF;
for (int i = 1; i <= cnt; i++) {
LL mul = 1, now = 0;
while (n / mul >= p[i].num) {
mul *= p[i].num;
now += n / mul;
}
ans = min(ans, now / p[i].tot);
}
cout << ans << endl;
return 0;
}