1 条题解
-
0
自动搬运
来自洛谷,原作者为

KesdiaelKen
**搬运于
2025-08-24 21:54:19,当前版本为作者最后更新于2018-06-05 14:47:41,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
看到,我们应该容易想到将它转化成(容斥基本操作)。但是这个东西怎么求呢?
下面,我们引出两个定理和一个算法。
1.因数个数定理
设,其中均为互不相等的质数(的质因数),则的因数个数为。
证明:
设的一个约数为,则必能表示为,其中。则的取值总共有种。所以k的取值总共有$$\prod_{i=1}^m{(a_i+1)}$$
2.(我也不知道它叫什么名字)
设表示的约数个数,求。
解:
对于我们可以进行适当的转换得到一个与之相等的式子:$$\sum^n_{i=1}[i|x]$$
再对其进行转换:
$$\sum^n_{i=1}\sum^{\lfloor\frac{n}{i}\rfloor}_{j=1}[i*j==x] $$看起来是更加复杂了。我们再将它带到原式中:
$$\sum^n_{i=1}f(x)=\sum^n_{x=1}\sum^n_{i=1}\sum^{\lfloor\frac{n}{i}\rfloor}_{j=1}[i*j==x]=\sum^n_{i=1}\sum^{\lfloor\frac{n}{i}\rfloor}_{j=1}=\sum^n_{i=1}\lfloor\frac{n}{i}\rfloor $$完成了转换。
3.整除分块
它的主要功能,就是将一个形如(当然不是只能在这个式子上应用,但它的确是最经常应用到整除分块的式子,没有之一)的式子的求值时间复杂度从降到。
整除分块能实现基于这样一个事实:的取值总共不会超过种。为什么呢,我们来证明一下:
当时:
我们需要证明:$\lfloor\frac{n}{i}\rfloor\not=\lfloor\frac{n}{i+1}\rfloor$
我们设,那么就有。根据除法的性质,,而又因为,所以,所以。
如果$\lfloor\frac{n}{i}\rfloor=\lfloor\frac{n}{i+1}\rfloor$,那么就可以表示为(),即。而我们又知道。所以,即等式两边矛盾。所以由反证法我们就得到了$\lfloor\frac{n}{i}\rfloor\not=\lfloor\frac{n}{i+1}\rfloor$。因此,在此情况下的取值个数就等于的取值数,即种。
当时:
这个不用怎么说了吧……都已经是小于的了,总取值数当然不超过啊。
所以,两类加起来就是种了。$$\mathcal{Q.E.D}$$
既然证玩了这个结论,我们就可以考虑这样一个思路:因为的取值数为(那个是常数,可以忽略),那么只要求出它取每一种值时的最大值和最小值是多少,最终求和的时候用前缀和预处理算一下每一段的值是多少,加起来就可以了。
那么接下来,我们又需要证明一个结论了:
如果已知正整数(),则使$\lfloor\frac{n}{i}\rfloor=\lfloor\frac{n}{p}\rfloor$的最大整数的值就是。
证明:
我们同样分类讨论一下。
当时:
我们设,那么就有。根据除法的性质,,而又因为,所以,所以。而的值就是。
那么,就会有$\lfloor\frac{n}{\frac{n}{p}}\rfloor=\lfloor\frac{n}{k}\rfloor$。在此基础上,让我们再证明一个结论:。我们令,则。又因为而,所以,所以。因为且,所以我们可以得出:。所以:。又因为,所以必须为。所以就证完了。而又由我们上面证的结论:的取值总共不会超过种可以知道当的时候,所有的值都不相同,即。所以,得证了。
当时:
我们设,那么就有。根据除法的性质,。而的值就是。
那么,就会有$\lfloor\frac{n}{\frac{n}{p}}\rfloor=\lfloor\frac{n}{k}\rfloor$。而我们现在要证明的,就是。看上去很难证,但是我们注意到必须符合且只需要符合的两个条件:$\lfloor\frac{n}{i_{max}}\rfloor=\lfloor\frac{n}{p}\rfloor=k,\lfloor\frac{n}{i_{max}+1}\rfloor\not=\lfloor\frac{n}{p}\rfloor=k$。那么,如果我们需要证明,那么就只需要说明$\lfloor\frac{n}{\lfloor\frac{n}{k}\rfloor}\rfloor=\lfloor\frac{n}{p}\rfloor=k\space\space and\space\space\lfloor\frac{n}{\lfloor\frac{n}{k}\rfloor+1}\rfloor\not=\lfloor\frac{n}{p}\rfloor=k$。看到$\lfloor\frac{n}{\lfloor\frac{n}{k}\rfloor}\rfloor=k$你想到了什么?
聪明的读者一定已经想到了,因为这个(讲了这么多这个不可能不会自行理解吧),所以这个结论在上面讨论的时候已经证过了。所以,得证啦!
综合上面两个结论,我们便可以得出整除分块的思路了:
-
令
-
对于当前的求得,设为
-
通过前缀和或公式(例如等差数列公式)求得函数(中的)的自变量从一直到的函数值的总和,并且加进
-
我们已知$\lfloor\frac{n}{j}\rfloor\not=\lfloor\frac{n}{j+1}\rfloor$,所以我们让。如果现在的仍然小于,则跳转第步,否则结束
最终得到的就是答案了。
综合上面的三项内容,思路就很明显了,相信各位如果仔细看了的话,一定已经完全明白这道题该怎么做了。
代码:
#include<cstdio> #include<algorithm> #include<cstring> #include<string> #include<cmath> #include<iostream> using namespace std; int main() { long long left,right; scanf("%lld%lld",&left,&right); long long sum1=0,sum2=0; for(long long zuo=1,you;zuo<=right;zuo=you+1) { you=right/(right/zuo); sum1=(sum1+(right/zuo)%998244353*((you-zuo+1)%998244353)%998244353)%998244353; } for(long long zuo=1,you;zuo<=left-1;zuo=you+1) { you=(left-1)/((left-1)/zuo); sum2=(sum2+((left-1)/zuo)%998244353*((you-zuo+1)%998244353)%998244353)%998244353; } printf("%lld\n",((sum1-sum2)%998244353+998244353)%998244353);//熟练运用取余操作的一些技巧 return 0; } -
- 1
信息
- ID
- 2877
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 5
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者