题目链接:哆啦A梦传送门
题意:
求
f
(
n
)
=
∑
i
=
1
n
∑
j
=
1
i
⌈
n
i
⌉
[
g
c
d
(
i
,
j
)
=
=
1
]
f(n)=\sum_{i=1}^{n}\sum_{j=1}^{i}\lceil \frac{n}{i} \rceil [gcd(i,j)==1]
f(n)=∑i=1n∑j=1i⌈in⌉[gcd(i,j)==1]
题解:参考博客:神犇
此公式大部分都是参考博客里面的。写这篇只是为了自己以后好复习回顾。
我们先化简一下:
f ( n ) = ∑ i = 1 n ∑ j = 1 i ⌈ n i ⌉ [ g c d ( i , j ) = = 1 ] = ∑ i = 1 n ( ∑ j = 1 i ⌊ n i ⌋ [ g c d ( i , j ) = = 1 ] + ϕ ( n ) − 1 ) 只 有 n 与 i 互 质 时 , 向 上 取 整 才 会 多 1 = ∑ i = 1 n ∑ j = 1 i ( ⌊ n i ⌋ [ g c d ( i , j ) = = 1 ] ) + ∑ i = 1 n ϕ ( n ) − n \begin{aligned} f(n)&=\sum_{i=1}^{n}\sum_{j=1}^{i}\lceil \frac{n}{i} \rceil [gcd(i,j)==1]\\ &=\sum_{i=1}^{n}(\sum_{j=1}^{i}\lfloor \frac{n}{i} \rfloor [gcd(i,j)==1]+\phi(n)-1) 只有n与i互质时,向上取整才会多1\\ &=\sum_{i=1}^{n}\sum_{j=1}^{i}(\lfloor \frac{n}{i} \rfloor [gcd(i,j)==1])+\sum_{i=1}^{n}\phi(n)-n\\ \end{aligned} f(n)=i=1∑nj=1∑i⌈in⌉[gcd(i,j)==1]=i=1∑n(j=1∑i⌊in⌋[gcd(i,j)==1]+ϕ(n)−1)只有n与i互质时,向上取整才会多1=i=1∑nj=1∑i(⌊in⌋[gcd(i,j)==1])+i=1∑nϕ(n)−n
我们再设:
首先我们要知道莫比乌斯函数有这样一个性质:
∑
d
∣
n
u
(
d
)
=
[
n
=
=
1
]
\sum_{d|n}u(d) =[n==1]
∑d∣nu(d)=[n==1]
g
(
n
)
=
∑
i
=
1
n
∑
j
=
1
i
(
⌊
n
i
⌋
[
g
c
d
(
i
,
j
)
=
=
1
]
)
=
∑
i
=
1
n
∑
j
=
1
i
(
⌊
n
i
⌋
∑
d
∣
(
i
,
j
)
u
(
d
)
)
我
们
现
在
枚
举
d
,
设
i
=
k
1
d
,
j
=
k
2
d
,
那
么
有
=
∑
d
=
1
n
u
(
d
)
∑
k
1
n
/
d
∑
k
2
k
1
⌊
k
1
k
2
⌋
\begin{aligned}g(n)&=\sum_{i=1}^{n}\sum_{j=1}^{i}(\lfloor \frac{n}{i} \rfloor [gcd(i,j)==1])\\ &=\sum_{i=1}^{n}\sum_{j=1}^{i}(\lfloor \frac{n}{i} \rfloor \sum_{d|(i,j)}u(d))\\ 我们现在枚举d,设i=k_1d,j=k_2d,那么有\\ &=\sum_{d=1}^{n}u(d)\sum_{k_1}^{n/d}\sum_{k_2}^{k_1}\lfloor \frac{k_1}{k_2}\rfloor \\ \end{aligned}
g(n)我们现在枚举d,设i=k1d,j=k2d,那么有=i=1∑nj=1∑i(⌊in⌋[gcd(i,j)==1])=i=1∑nj=1∑i(⌊in⌋d∣(i,j)∑u(d))=d=1∑nu(d)k1∑n/dk2∑k1⌊k2k1⌋
我们知道:
∑
i
=
1
n
⌊
n
i
⌋
=
∑
i
=
1
n
σ
(
i
)
,
σ
(
i
)
表
示
i
的
正
因
子
个
数
。
\begin{aligned}\sum_{i=1}^{n}\lfloor \frac{n}{i}\rfloor=\sum_{i=1}^{n} \sigma(i) , \sigma(i)表示i的正因子个数。\end{aligned}
i=1∑n⌊in⌋=i=1∑nσ(i),σ(i)表示i的正因子个数。
一
个
很
简
单
的
证
明
,
对
于
每
个
i
,
⌊
n
i
⌋
表
示
在
[
1
,
n
]
中
有
⌊
n
i
⌋
个
因
子
i
例
如
:
i
等
于
1
,
n
=
4
,
⌊
4
1
⌋
=
4
,
即
在
[
1
,
4
]
中
每
个
数
都
存
在
因
子
1
\begin{aligned} 一个很简单的证明,对于每个i,\lfloor \frac{n}{i}\rfloor表示在[1,n]中有\lfloor \frac{n}{i}\rfloor个因子i\\ 例如:i等于1,n=4, \lfloor \frac{4}{1}\rfloor=4,即在[1,4]中每个数都存在因子1\end{aligned}
一个很简单的证明,对于每个i,⌊in⌋表示在[1,n]中有⌊in⌋个因子i例如:i等于1,n=4,⌊14⌋=4,即在[1,4]中每个数都存在因子1
那么上式就可化简为:
g
(
n
)
=
∑
d
=
1
n
u
(
d
)
∑
k
1
n
/
d
∑
k
2
k
1
⌊
k
1
k
2
⌋
=
∑
d
=
1
n
u
(
d
)
∑
k
1
n
/
d
∑
k
2
k
1
σ
(
k
2
)
\begin{aligned}g(n)&=\sum_{d=1}^{n}u(d)\sum_{k_1}^{n/d}\sum_{k_2}^{k_1}\lfloor \frac{k_1}{k_2}\rfloor \\ &=\sum_{d=1}^{n}u(d)\sum_{k_1}^{n/d}\sum_{k_2}^{k_1} \sigma(k_2)\\\end{aligned}
g(n)=d=1∑nu(d)k1∑n/dk2∑k1⌊k2k1⌋=d=1∑nu(d)k1∑n/dk2∑k1σ(k2)
我们设 h ( n ) = ∑ i n ∑ j i σ ( j ) \begin{aligned}h(n)=\sum_{i}^{n}\sum_{j}^{i} \sigma(j)\end{aligned} h(n)=i∑nj∑iσ(j),这个我们可以先线性筛出来 σ ( n ) \sigma(n) σ(n),接着预处理前缀和就可以求得 h ( n ) h(n) h(n)。
那么最终的式子就为:
f
(
n
)
=
∑
d
=
1
n
u
(
d
)
h
(
n
d
)
+
∑
i
=
1
n
ϕ
(
n
)
−
n
\begin{aligned}f(n)=\sum_{d=1}^{n}u(d)h(\frac{n}{d})+\sum_{i=1}^{n}\phi(n)-n\end{aligned}
f(n)=d=1∑nu(d)h(dn)+i=1∑nϕ(n)−n
我们现在总结下:
根据题目给的公式或者自己推的公式:
1,如果有向上取整的,先化成向下取整(一般跟欧拉函数挂钩)。
2,看到有某个 [条件变量=1],我们此时要能反应出莫比乌斯反演的一个性质:
∑
d
∣
条
件
变
量
u
(
d
)
\sum_{d|条件变量}u(d)
∑d∣条件变量u(d) ,接着我们就把d给拿出来枚举,并让其它积分变量满足相应的条件(一般n/d等等)
3,接着我们要熟记一些公式,因为我们可以将它们替换,例如此题的
∑
i
=
1
n
⌊
n
i
⌋
=
∑
i
=
1
n
σ
(
i
)
,
σ
(
i
)
表
示
i
的
正
因
子
个
数
。
\begin{aligned}\sum_{i=1}^{n}\lfloor \frac{n}{i}\rfloor=\sum_{i=1}^{n} \sigma(i) , \sigma(i)表示i的正因子个数。\end{aligned}
i=1∑n⌊in⌋=i=1∑nσ(i),σ(i)表示i的正因子个数。公式。
4,有些化简后的式子不是我们常用的能被替换的公式(此公式很容易求得),那么此时就很可能要想到这是不是积性函数,要是的话,我们就要往这方面去做了,但有时积性函数不好判断,也可以大胆假设它就为积性函数,因为大部分我们遇到的都是积性函数。不过我们还是得到掌握下积性函数的判别方法,比如,我们要积累一些积性函数,多个积性函数相乘也为积性函数。知道是积性函数之后,我们就可以在线性筛那里把它们给筛出来。
线性筛分为3部分:
1.n本身是素数,这个根据积性函数的定义可得,很容易求。
2.i%prime[j]!=0,这个也是根据积性函数的性质可得,即f(a)f(b)=f(ab)。
3.i%prime[j]==0,这个可能需要找规律加灵光一闪。
代码:
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
typedef long long LL;
const LL mod=1e9+7;
int prime[N],tot;/// 筛素数 ,从0下标开始存储
int mu[N];///莫比乌斯函数
int phi[N]; ///欧拉函数
///facnum[i]表示i的约数个数,d[i],表示i的最小质因子的次幂
int facnum[N],d[N];
bool vis[N];
///函数h,欧拉函数前缀和,莫比乌斯前缀和
LL h[N],sum_phi[N],sum_mu[N];
void init()
{
tot = 0;
phi[1] = 1;
mu[1] = 1;
facnum[1] = 1;
for(int i = 2; i < N; i++)
{
if(!vis[i])
{
phi[i] = i - 1;
mu[i] = -1;
prime[tot++] = i;
facnum[i] = 2;
d[i] = 1;
}
for(int j = 0; j < tot && i * prime[j] < N; j++)
{
vis[i * prime[j]] = true;
if(i % prime[j] == 0)
{
phi[i * prime[j]] = phi[i] * prime[j];
mu[i * prime[j]] = 0;
facnum[i * prime[j]] = facnum[i] / (d[i] + 1) * (d[i] + 2);
d[i * prime[j]] = d[i] + 1;
break;
}
phi[i * prime[j]] = phi[i] * (prime[j] - 1);
mu[i * prime[j]] = -mu[i];
facnum[i * prime[j]] = facnum[i] * 2;
d[i * prime[j]] = 1;
}
}
sum_phi[0]=0;
LL item=0;
for(int i=1;i<N;i++){
sum_phi[i]=(sum_phi[i-1]+phi[i])%mod;
sum_mu[i]=sum_mu[i-1]+mu[i];
///递推求h(i)
item=(item+facnum[i])%mod;
h[i]=(h[i-1]+item)%mod;
}
}
int main()
{
init();
int n;
while(~scanf("%d",&n))
{
int r;
LL item=(sum_phi[n]-n+mod)%mod;
for(int l=1;l<=n;l=r+1){
r=n/(n/l);
item=(item+(sum_mu[r]-sum_mu[l-1]+mod)%mod*h[n/l]%mod)%mod;
}
printf("%lld\n",item);
}
return 0;
}
我的标签:做个有情怀的程序员。