function
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1700 Accepted Submission(s): 607
Problem Description
There is a function f(x),which is defined on the natural numbers set N,satisfies the following eqaution
N 2 − 3 N + 2 = ∑ d ∣ N f ( d ) N^2−3N+2=∑_{d|N}f(d) N2−3N+2=∑d∣Nf(d)
calulate ∑ i = 1 N f ( i ) ∑^N_{i=1}f(i) ∑i=1Nf(i) mod 109+7.
Input
the first line contains a positive integer T,means the number of the test cases.
next T lines there is a number N
T≤500,N≤109
only 5 test cases has N>106.
Output
Tlines,each line contains a number,means the answer to the i-th test case.
Sample Input
1
3
Sample Output
2
1
2
−
3
∗
1
+
2
=
f
(
1
)
=
0
1^2-3*1+2=f(1)=0
12−3∗1+2=f(1)=0
2
2
−
3
∗
2
+
2
=
f
(
2
)
+
f
(
1
)
=
0
−
>
f
(
2
)
=
0
2^2-3*2+2=f(2)+f(1)=0->f(2)=0
22−3∗2+2=f(2)+f(1)=0−>f(2)=0
3
2
−
3
∗
3
+
2
=
f
(
3
)
+
f
(
1
)
=
2
−
>
f
(
3
)
=
2
3^2-3*3+2=f(3)+f(1)=2->f(3)=2
32−3∗3+2=f(3)+f(1)=2−>f(3)=2
f
(
1
)
+
f
(
2
)
+
f
(
3
)
=
2
f(1)+f(2)+f(3)=2
f(1)+f(2)+f(3)=2
题意
有这么一个函数
f
(
x
)
f(x)
f(x)满足
N
2
−
3
N
+
2
=
∑
d
∣
N
f
(
d
)
N^2-3N+2=\sum_{d|N}f(d)
N2−3N+2=d∣N∑f(d)
然后求
∑
i
=
1
n
f
(
i
)
m
o
d
1
0
9
+
7
\sum_{i=1}^nf(i)\ mod\ 10^9+7
i=1∑nf(i) mod 109+7
思路
令
g
(
n
)
=
n
2
−
3
n
+
2
g(n)=n^2-3n+2
g(n)=n2−3n+2
那么有
g
(
n
)
=
(
I
∗
f
)
(
n
)
g(n)=(I*f)(n)
g(n)=(I∗f)(n)
左边是恒等函数
I
I
I和
f
f
f的狄利克雷卷积,那么根据
I
∗
μ
=
e
I*\mu=e
I∗μ=e,两边再乘上一个
μ
\mu
μ,有
(
μ
∗
g
)
=
(
μ
∗
I
)
∗
f
(\mu*g)=(\mu*I)*f
(μ∗g)=(μ∗I)∗f
(
μ
∗
g
)
=
f
(\mu*g)=f
(μ∗g)=f
所以有
f
(
n
)
=
∑
d
∣
n
μ
(
d
)
g
(
n
d
)
f(n)=\sum_{d|n}\mu(d)g(\frac{n}{d})
f(n)=d∣n∑μ(d)g(dn)
那么
∑
i
=
1
n
f
(
n
)
=
∑
i
=
1
n
∑
d
∣
i
μ
(
d
)
g
(
i
d
)
\sum_{i=1}^nf(n)=\sum_{i=1}^n\sum_{d|i}\mu(d)g(\frac{i}{d})
i=1∑nf(n)=i=1∑nd∣i∑μ(d)g(di)
当前的含义是枚举
1
−
n
1-n
1−n中每一个i的因子,这个和枚举
1
−
n
1-n
1−n中每一个数的倍数是等价的,那么就有
∑
i
=
1
n
f
(
n
)
=
∑
d
=
1
n
μ
(
d
)
∑
d
∣
i
g
(
i
d
)
\sum_{i=1}^nf(n)=\sum_{d=1}^n\mu(d)\sum_{d|i}g(\frac{i}{d})
i=1∑nf(n)=d=1∑nμ(d)d∣i∑g(di)
∑
i
=
1
n
f
(
n
)
=
∑
d
=
1
n
μ
(
d
)
∑
i
=
1
⌊
n
d
⌋
g
(
i
)
\sum_{i=1}^nf(n)=\sum_{d=1}^n\mu(d)\sum_{i=1}^{\left \lfloor \frac{n}{d} \right \rfloor}g(i)
i=1∑nf(n)=d=1∑nμ(d)i=1∑⌊dn⌋g(i)
令
S
(
n
)
=
∑
i
=
1
n
g
(
i
)
S(n)=\sum_{i=1}^ng(i)
S(n)=∑i=1ng(i)则有
S
(
n
)
=
∑
i
=
1
n
i
2
−
3
∑
i
=
1
n
i
+
∑
i
=
1
n
2
S(n)=\sum_{i=1}^ni^2-3\sum_{i=1}^ni+\sum_{i=1}^n2
S(n)=i=1∑ni2−3i=1∑ni+i=1∑n2
S
(
n
)
=
n
(
n
+
1
)
(
2
n
+
1
)
6
−
3
n
(
n
+
1
)
2
+
2
n
S(n)=\frac{n(n+1)(2n+1)}{6}-3\frac{n(n+1)}{2}+2n
S(n)=6n(n+1)(2n+1)−32n(n+1)+2n
那么原式就有
∑
i
=
1
n
f
(
n
)
=
∑
d
=
1
n
μ
(
d
)
S
(
⌊
n
d
⌋
)
\sum_{i=1}^nf(n)=\sum_{d=1}^n\mu(d)S(\left \lfloor \frac{n}{d} \right \rfloor)
i=1∑nf(n)=d=1∑nμ(d)S(⌊dn⌋)
∑
i
=
1
n
f
(
n
)
=
∑
d
=
1
n
μ
(
d
)
(
⌊
n
d
⌋
(
⌊
n
d
⌋
+
1
)
(
2
⌊
n
d
⌋
+
1
)
6
−
3
⌊
n
d
⌋
(
⌊
n
d
⌋
+
1
)
2
+
2
⌊
n
d
⌋
)
\sum_{i=1}^nf(n)=\sum_{d=1}^n\mu(d)(\frac{\left \lfloor \frac{n}{d} \right \rfloor(\left \lfloor \frac{n}{d} \right \rfloor+1)(2\left \lfloor \frac{n}{d} \right \rfloor+1)}{6}-3\frac{\left \lfloor \frac{n}{d} \right \rfloor(\left \lfloor \frac{n}{d} \right \rfloor+1)}{2}+2\left \lfloor \frac{n}{d} \right \rfloor)
i=1∑nf(n)=d=1∑nμ(d)(6⌊dn⌋(⌊dn⌋+1)(2⌊dn⌋+1)−32⌊dn⌋(⌊dn⌋+1)+2⌊dn⌋)
莫比乌斯函数的前缀和就可以用杜教筛求了,和函数就可以用分块来做,提前处理一下6的逆元和2的逆元就可以了
#include<bits/stdc++.h>
using namespace std;
const int N=5e6+5;
const int mod=1e9+7;
const int inv6=166666668;
const int inv2=500000004;
bool vis[N];
int mu[N];
int prime[N];
int cnt;
void init()
{
cnt=0;
mu[1]=1;
for(int i=2;i<N;i++)
{
if(!vis[i])
{
prime[cnt++]=i;
mu[i]=-1;
}
for(int j=0;j<cnt&&i*prime[j]<=N;j++)
{
vis[i*prime[j]]=1;
if(i%prime[j]==0)
{
mu[i*prime[j]]=0;
break;
}
else
mu[i*prime[j]]=-mu[i];
}
}
for(int i=2;i<N;i++)
mu[i]=mu[i-1]+mu[i];
}
unordered_map<int,int>S;
int Sum(int n)
{
if(n<N) return mu[n];
else if(S.find(n)!=S.end())return S[n];
int ans=1;
for(int i=2,last;i<=n;i=last+1)
{
last=n/(n/i);
ans=ans-(last-i+1)*Sum(n/i);
}
S[n]=ans;
return ans;
}
int main()
{
init();
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
long long ans=0;
for(int i=1,last;i<=n;i=last+1)
{
last=n/(n/i);
long long m=n/i;
ans=(ans+(Sum(last)-Sum(i-1)+mod)%mod*(m*(m+1)%mod*(2*m%mod+1)%mod*inv6%mod-3*m%mod*(m+1)%mod*inv2%mod+2*m%mod+mod)%mod)%mod;
}
printf("%lld\n",ans);
}
return 0;
}