P3935 Calculating 题解

题目传送门

写在开头:建议升紫!!!

数学题…… 好难!!!

因数个数定理(题目里的公式)

既然题目已经提到了,我就浅浅证一下

……好吧打字太累了,画个图

得证!!!(爽!!!)

整除分块(实际上应该还有一个东西要证但是我没看懂,感觉没啥用,所以就跳过)

好难……

$$
它的主要功能,就是将一个形如\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;
}

下班!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值