河南萌新联赛2025第(四)场 B ----0!!!!!
题目链接: https://ac.nowcoder.com/acm/contest/115184/B
蒟蒻第一次写题解
♠题面
给定两个整数 L 和 R (L ≤ R),求区间 [L , R] 中所有整数的因数乘积末尾的零的个数。(1≤L≤R≤\(10^{10}\))
♣思路
数论分块
首先,\(F_p(n)\)为在区间[1 , n]中 ,所有整数的 “因数乘积” 里,能被 \(p^x\) 整除的最大非负整数 x 。
即把把 1 到 n 每个数的因数全部乘起来,这个巨大乘积中,最多包含多少个 p 的因子(即最大的 x ,让 \(p^x\) 能整除这个乘积 )
由于需要求的是因数乘积末尾的 0 的个数,所以这个个数与因子 2 和 5 的个数有关,只需要统计区间内因子 2 和 5 的个数,取其最小值即可。
即min{\(F_2(R)\) - \(F_2(L-1)\),\(F_5(R)\) - \(F_5(L-1)\)}
回到\(F_p(n)\),我们可以得到
\[F_p(n)=\sum_{i = 1}^n\sum_{d|i}\sum_{k = 1}^{[p^k|d]} [p^k|d]
\]
- \([p^k|d]\)是一个指示函数,如果d可以整除\(p^k\),该表达式结果为1,否则为0。以d=12,p=2为例,k=1和k=2时,\(p^k\)=2,4,可以被d整除,结果为1,当k=3的时候\(p^k\)=8,不能被d整除,所以12中包含2个2因子。\(\sum_{k = 1}^{[p^k|d]} [p^k|d]\)这个式子得出来的结果就是d中包含的p的因子的个数
- \(\sum_{d|i}\)则表示所有i的因子(d)中p因子的个数
- \(\sum_{i = 1}^n\)同理表示1到n之间的数
- \(F_p(n)=\sum_{i = 1}^n\sum_{d|i}\sum_{k = 1}^{[p^k|d]} [p^k|d]\)即是区间[1 , n]中,所有整数的因数乘积里,能被 \(p^x\) 整除的最大非负整数 x
接下来交换求和次序,将k提前
\[F_p(n)=\sum_{k = 1}^n\sum_{i = 1}^n\sum_{d|i} [p^k|d]
\]
- 这是调整计算顺序,从 “先数、再因数、再看 \(p^k\) ”,变成 “先定 \(p^k\) ,再找含它的数和因数” 。
然后更换一下枚举对象,从枚举数到枚举约数
\[F_p(n) = \sum_{k=1}^n \sum_{\substack{d=1 \\ p^k \mid d}}^n \left\lfloor \frac{n}{d} \right\rfloor
\]
- 由于d是\(p^k\)的倍数,而i是d的倍数。统计有多少个i能够整除d,即\(\left\lfloor \frac{n}{d} \right\rfloor\)。
- 这一步把 “数 i 及其因数 d ” 的关系,转化成 “直接找含 \(p^k\) 的 d ,再算倍数个数”
简化式子,同除\(p^k\)
\[F_p(n)=\sum_{k = 1}^{\lfloor \frac{n}{p^k} \rfloor}\sum_{d = 1}^{\lfloor \frac{n}{p^k} \rfloor} \lfloor \frac{n}{p^k \cdot d} \rfloor
\]
- 因为 d 是 \(p^k\) 的倍数,设 \(d = p^k \cdot t\)(t 是正整数 )
接下来对k进行枚举,内层进行数论分块就可以得到结果。
♥Code
点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
using i64 = long long;
using u64 = unsigned long long;
using i128 = __int128;
using ldb = long double;
#define all(x) (x).begin(), (x).end()
i64 Fp(i64 x, i64 nn)
{
i64 num = 0;
for (i64 i = x; i <= nn; i *= x)
{
i64 n = nn / i;
for (i64 l = 1; l <= n; l = n / (n / l) + 1)
{
i64 r = n / (n / l);
num += (r - l + 1) * (n / l);
}
}
return num;
}
void solve()
{
i64 L, R;
cin >> L >> R;
i64 a = Fp(2, R) - Fp(2, L - 1);
i64 b = Fp(5, R) - Fp(5, L - 1);
cout << min(a, b) << endl;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
i64 t = 1;
//cin >> t;
while (t--)
{
solve();
}
return 0;
}
没了qwq


浙公网安备 33010602011771号