Description
很久很久以前,有一只神犇叫yzy;
很久很久之后,有一只蒟蒻叫lty;
请你读入一个整数N;1<=N<=1E9,A、B模1E9+7;
请你输出一个整数
A=∑Ni=1μ(i2)
A
=
∑
i
=
1
N
μ
(
i
2
)
请你输出一个整数
B=∑Ni=1φ(i2)
B
=
∑
i
=
1
N
φ
(
i
2
)
Solution
第一问非常sb,回想μ的定义可知答案一定为1
第二问可以变成求
B=∑Ni=1φ(i)i
B
=
∑
i
=
1
N
φ
(
i
)
i
熟练掌握了杜教筛的我敏锐发觉这可做,省去一堆套路可得到
S(N)=N(N+1)(2N+1)6−∑Ni=2d×S(⌊Nd⌋)
S
(
N
)
=
N
(
N
+
1
)
(
2
N
+
1
)
6
−
∑
i
=
2
N
d
×
S
(
⌊
N
d
⌋
)
主要做法就是令 f(i)=φ(i)i f ( i ) = φ ( i ) i ,令 g(i)=i g ( i ) = i ,然后对这两个函数的迪利克雷卷积求前缀和
然后就是套杜教筛就行了。交错题目连续WA我也很难受
Code
#include <stdio.h>
#include <string.h>
#include <map>
#define rep(i,st,ed) for (int i=st;i<=ed;++i)
typedef long long LL;
const int MOD=1000000007;
const int N=10000000;
const int ny6=166666668;
int prime[N/10];
LL f[N];
bool not_prime[N+5];
std:: map <LL,LL> map;
void pre_work() { f[1]=1;
rep(i,2,N) {
if (!not_prime[i]) {
prime[++prime[0]]=i;
f[i]=i-1;
}
for (int j=1;i*prime[j]<=N&&j<=prime[0];j++) {
not_prime[i*prime[j]]=1;
if (i%prime[j]==0) {
f[i*prime[j]]=f[i]*prime[j];
break;
}
f[i*prime[j]]=f[i]*(prime[j]-1);
}
}
rep(i,1,N) f[i]=(f[i-1]+f[i]*i%MOD)%MOD;
}
LL S(LL n) {
if (n%2) return ((n+1)/2)%MOD*n%MOD;
return (n/2)%MOD*(n+1)%MOD;
}
LL calc(LL n) {
if (n<=N) return f[n];
if (map[n]) return map[n];
LL ret=0;
for (LL i=2,j;i<=n;i=j+1) {
j=n/(n/i);
ret=(ret+(S(j)-S(i-1)+MOD)%MOD*calc(n/i)%MOD)%MOD;
}
ret=(n*(n+1)%MOD*(2*n+1)%MOD*ny6%MOD-ret+MOD)%MOD;
map[n]=ret;
return ret;
}
int main(void) {
pre_work();
LL n; scanf("%lld",&n);
printf("1\n%lld\n", calc(n));
return 0;
}