写在开头:建议升紫!!!
数学题…… 好难!!!
因数个数定理(题目里的公式)
既然题目已经提到了,我就浅浅证一下
……好吧打字太累了,画个图
得证!!!(爽!!!)
整除分块(实际上应该还有一个东西要证但是我没看懂,感觉没啥用,所以就跳过)
好难……
$$
它的主要功能,就是将一个形如\sum^n _{i=1} ⌊ i / n ⌋ 的式子将O(n)的复杂度降到O(\sqrt{n})
$$
看上去十分神经,但实际上也十分神经
显然:答案不超过2\sqrt{n}个
证明!!!(好烦):
$$
1.当x<\sqrt{n}时,\lfloor \frac{x}{n} \rfloor显然只有\sqrt{n}个
$$
$$
2.当x>\sqrt{r}时,\lfloor \frac{n}{x}\rfloor\leq\sqrt{n},那也只有\sqrt{n}个
$$
这样我们就可以对这o(\sqrt{n})个块进行计算就可以了
但是!!!这样只能解决l=1的情况
所以对于l \neq 1直接差分即可
最后算一下复杂度:O(\sqrt{n})稳稳过!!!
接着就可以上AC code啦:
#include<bits/stdc++.h> using namespace std; const int mod=998244353; long long i,j,k,l; long long sum1,sum2; long long L,R; int main() { scanf("%lld%lld",&L,&R); for(i=1,j;i<=R;i=j+1) { j=R/(R/i);// 求长度 sum1=(sum1+(R/i)%mod*((j-i+1)%mod)%mod)%mod; } j=0; for(i=1,j;i<=L-1;i=j+1) { j=(L-1)/((L-1)/i);// 求长度 sum2=(sum2+((L-1)/i)%mod*((j-i+1)%mod)%mod)%mod; } printf("%lld",((sum1-sum2)%mod+mod)%mod); return 0; }
下班!!!