整数分块(数论分块)应用 ----除数函数求和 2

版权声明:转载注明下出处就行了。 https://blog.csdn.net/LJD201724114126/article/details/82751920

整数分块参考博客,很重要http://www.cnblogs.com/0xfffe/p/9648943.html

有个问题:

求   \small \sum_{i=1}^{N} \left \lfloor \frac{N}{i} \right \rfloor , N\leq 10^{12},

直接做肯定T

我们打表之后发现有如下性质:

1,\small {\color{Red} \left \lfloor \frac{N}{i} \right \rfloor{\color{Red} }}  最多有 \small {\color{Red} 2\sqrt{N}} 种。

证明:对于 \small i\leq \sqrt{N} ,只有 \small \sqrt{N} 种,对于 \small i>\sqrt{N},   \small \frac{N}{i}<\sqrt{N} 。

扫描二维码关注公众号,回复: 3943293 查看本文章
///数论分块 参考博客:http://www.cnblogs.com/0xfffe/p/9648943.html
///https://www.cnblogs.com/hehe54321/p/9298945.html
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;

typedef long long LL;
const LL mod=998244353;

LL sum(LL x)
{
    return x*(x+1)%mod*(2*x+1)%mod*166374059%mod;///求前1^2+2^2+3^2+4^2+... 和
}

int main()
{
    LL n,ans;
    LL a0,a1,a2;
    while(~scanf("%lld",&n))
    {
        a0=a1=a2=0;
        LL i,j;
        for( i=1;i<=n;i=j+1)
        {
            LL item=n/i;
            j=n/item; ///j表示从i到j,其n/i都是相等的,这是数论分块
            a0=(a0+(j-i+1)*item)%mod; ///有(j-i+1)个item值
            a1=(a1+(i+j)*(j-i+1)%mod*499122177%mod*item%mod)%mod;///连续的从i到j,其n/i都想等,等差数列求和就行了
            a2=(a2+(sum(j)-sum(i-1)+mod)%mod*item%mod)%mod;///公式求前平方和
        }

        printf("%lld\n",(2*a2%mod+3*a1%mod+5*a0%mod)%mod);
    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/LJD201724114126/article/details/82751920