Description
给定 \(n \le 10^7,k\),求 \(\sum_{i=1}^n \sigma_k (i)\),其中 \(\sigma_k(n)=\sum_{d|n} d^k\)。
Solution
自然想到交换求和顺序,即
\[\sum_{i=1}^n \sigma_k(i) =\sum_{i=1}^n \sum_{d|i} d^k=\sum_{i=1}^n[\frac n i]i^k
\]
于是,不妨设 \(f(i)=i^k\),则我们可以对每个 \(f(i)\) 在 \(O(\log n)\) 时间内计算,故总时间复杂度为 \(O(n\log n)\)。由于评测机很快,这样已经能卡过去了。
考虑到 \(f(i)\) 是完全积性的,我们可以分出 \(i\) 对最小素因子 \(p_i\),利用线性筛计算所有合数的 \(f(i)\)。这样复杂度为 \(O(n+\frac n {\log n} \log n)=O(n)\),可以接受。
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 10000005;
const int mod = 1e9+7;
int isp[N],vp[N],f[N],pcnt,n,k,ans;
int qpow(int p,int q)
{
return (q&1?p:1)*(q?qpow(p*p%mod,q/2):1)%mod;
}
signed main()
{
ios::sync_with_stdio(false);
cin>>n>>k;
for(int i=2;i<=n;i++)
{
isp[i]=1;
}
for(int i=2;i<=n;i++)
{
if(isp[i])
{
vp[++pcnt]=i;
f[i]=qpow(i,k);
}
for(int j=1;j<=pcnt&&vp[j]*i<=n;j++)
{
isp[i*vp[j]]=0;
f[i*vp[j]]=f[i]*f[vp[j]]%mod;
if(i%vp[j]==0) break;
}
}
for(int i=1;i<=n;i++)
{
ans=(ans+(n/i)*f[i]%mod)%mod;
}
cout<<(ans+n)%mod<<endl;
//system("pause");
}