题目大意
设 x x x 的质因数分解为 p 1 c 1 p 2 c 2 ⋯ p m c m p_1^{c_1}p_2^{c_2}\cdots p_m^{c_m} p1c1p2c2⋯pmcm,记 f ( x ) = c 1 p 1 c 2 p 2 ⋯ c m p m f(x) = c_1^{p_1}c_2^{p_2}\cdots c_m^{p_m} f(x)=c1p1c2p2⋯cmpm,给定 n n n,求 ∑ i = 1 n f ( n ) m o d 1 0 9 + 7 \sum_{i=1}^n f(n) \bmod 10^9+7 ∑i=1nf(n)mod109+7。
n
≤
1
0
14
n \le 10^{14}
n≤1014
10s
\\
\\
\\
题解
n
n
n 的这个范围没法筛,但却很根号。
因此用 powerful number 求积性函数和。
观察到对质数来说
f
(
p
)
=
1
f(p)=1
f(p)=1,能对上这个形式的,马上想到全 1 函数
1
(
n
)
=
1
1(n)=1
1(n)=1。然后观察
h
=
f
1
=
f
∗
μ
h = \frac{f}{1} = f * \mu
h=1f=f∗μ,得到
h
(
p
c
)
=
{
c
p
−
(
c
−
1
)
p
,
c
>
1
0
,
c
=
1
h(p^c)=\begin{cases} c^p-(c-1)^p, &c>1 \\ 0, &c=1 \end{cases}
h(pc)={cp−(c−1)p,0,c>1c=1
然后推式子
f
=
h
∗
1
⇒
∑
i
=
1
n
f
(
i
)
=
∑
i
=
1
n
∑
j
=
1
⌊
n
i
⌋
h
(
i
)
1
(
j
)
=
∑
i
=
1
n
h
(
i
)
⌊
n
i
⌋
\begin{aligned} & f = h * 1 \\ \Rightarrow & \sum_{i=1}^n f(i) = \sum_{i=1}^n \sum_{j=1}^{\lfloor \frac ni \rfloor} h(i)1(j) = \sum_{i=1}^n h(i) \lfloor \frac ni \rfloor \\ \end{aligned}
⇒f=h∗1i=1∑nf(i)=i=1∑nj=1∑⌊in⌋h(i)1(j)=i=1∑nh(i)⌊in⌋
又由于 h h h 只在 powerful number 处有值,因此用 dfs 把 O ( n ) O(\sqrt n) O(n) 个 powerful number 都找出来算答案就行了。dfs 的过程中要维护 h h h 的值, c p c^p cp 可以用快速幂算。
代码
#include<bits/stdc++.h>
#define fo(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
typedef long long LL;
const int maxp0=1e7+5;
const LL mo=1e9+7;
LL n;
int p[maxp0],p0;
bool bz[maxp0];
void Prime(int n) {
fo(i,2,n) {
if (!bz[i]) p[++p0]=i;
fo(j,1,p0) {
if (i*p[j]>n) break;
bz[i*p[j]]=1;
if (i%p[j]==0) break;
}
}
}
LL Pow(LL x,LL y) {
LL re=1;
for(; y; y>>=1, x=x*x%mo) if (y&1) re=re*x%mo;
return re;
}
LL ans;
void dfs(int k,LL h,LL i) {
if (k>p0) return;
if (n/i<(LL)p[k]*p[k]) return;
dfs(k+1,h,i);
LL last=1;
i*=p[k];
for(int c=2; ; c++) {
LL cur=Pow(c,p[k]);
LL newh=h*(cur-last+mo)%mo;
i*=p[k];
(ans+=(n/i)%mo*newh)%=mo;
dfs(k+1,newh,i);
if (n/i<p[k]) break;
last=cur;
}
}
int main() {
Prime(1e7);
scanf("%lld",&n);
ans=n%mo;
dfs(1,1,1);
printf("%lld\n",ans);
}