libreoj 125 除数函数求和2 题解

题意简述

给定 $n$,求 $\sum\limits_{i=1}^{n} 2\sigma_2(i)+3\sigma_1(i)+5\sigma_0(i)$

$n<=1e9$

其中 $\sigma_k(x)=x$ 所有因数的 $k$ 次方和。

思路

我们反过来想,枚举每个因数对答案产生了多少贡献。

显然,一个因数 $d$ 对答案产生的贡献就是 $2d^2+3d+5$。

那么有多少 $i$ 算到了这个 $d$ 呢?只要是 $d$ 的倍数,都能算到,所以一共有 $\lfloor \dfrac{n}{d}\rfloor$ 个。

答案变成了 $\sum\limits_{d=1}^{n} (2d^2+3d+5)\lfloor \dfrac{n}{d}\rfloor$

整除分块,一次 $O(\sqrt{n})$

代码

点击
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#include <bits/stdc++.h>
using namespace std;
namespace Flandre_Scarlet
{
    #define int long long 
    #define mod 998244353
    #define i2  499122177
    #define i6  166374059
    #define F(i,l,r) for(int i=l;i<=r;++i)
    #define D(i,r,l) for(int i=r;i>=l;--i)
    #define Fs(i,l,r,c) for(int i=l;i<=r;c)
    #define Ds(i,r,l,c) for(int i=r;i>=l;c)
    #define MEM(x,a) memset(x,a,sizeof(x))
    #define FK(x) MEM(x,0)
    #define Tra(i,u) for(int i=G.Start(u),__v=G.To(i);~i;i=G.Next(i),__v=G.To(i))
    #define p_b push_back
    #define sz(a) ((int)a.size())
    #define iter(a,p) (a.begin()+p)
    void R1(int &x)
    {
        x=0;char c=getchar();int f=1;
        while(c<'0' or c>'9') f=(c=='-')?-1:1,c=getchar();
        while(c>='0' and c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
        x=(f==1)?x:-x;
    }
    void Rd(int cnt,...)
    {
        va_list args;
        va_start(args,cnt);
        F(i,1,cnt) 
        {
            int* x=va_arg(args,int*);R1(*x);
        }
        va_end(args);
    }
    int n;
    void Input()
    {
        R1(n);
    }
    int s1(int x) {x%=mod; return x*(x+1)%mod*i2%mod;}
    int s2(int x) {x%=mod; return x*(x+1)%mod*(2*x+1)%mod*i6%mod;}
    int S(int x)  {return 5*x%mod+3*s1(x)%mod+2*s2(x)%mod;}
    void Soviet()
    {
        int ans=0;
        for(int l=1,r;l<=n;l=r+1)
        {
            r=n/(n/l);
            ans+=(n/l)%mod*(S(r)-S(l-1)+mod)%mod;
            ans%=mod;
        }
        printf("%lld\n",ans);
    }
    #define Flan void
    Flan IsMyWife()
    {
        Input();
        Soviet();
    }
    #undef int //long long 
}
int main()
{
    Flandre_Scarlet::IsMyWife();
    getchar();getchar();
    return 0;
}
w