Description
简化题意:求
∑
i
=
1
n
∑
j
∣
i
g
c
d
(
j
,
i
j
)
\sum _{i=1}^n \sum_{j|i} gcd(j,{i\over j})
i=1∑nj∣i∑gcd(j,ji)
Input
输入包含一行,一个正整数 n。
Output
输出只有一行, F(n)。
Sample Input
Sample Input1:
10
Sample Input2:
1000
Sample Output
Sample Output1:
32
Sample Output2:
12776
Data Constraint
n < = 1 0 11 n<=10^{11} n<=1011
Solution
两个sigma外加gcd,直接考虑反演
∑
i
=
1
n
∑
j
∣
i
g
c
d
(
j
,
i
j
)
\sum _{i=1}^n \sum_{j|i} gcd(j,{i\over j})
i=1∑nj∣i∑gcd(j,ji)
这里是枚举i和i的约数,我们转换为枚举i和i的倍数
∑
i
=
1
n
∑
j
=
1
⌊
n
i
⌋
g
c
d
(
i
,
j
)
\sum _{i=1}^n\sum _{j=1}^{\lfloor{n\over i}\rfloor} gcd(i,j)
i=1∑nj=1∑⌊in⌋gcd(i,j)
套路反演
设 f [ d ] = ∑ i = 1 n ∑ j = 1 ⌊ n i ⌋ g c d ( i , j ) = d f[d]=\sum _{i=1}^n\sum _{j=1}^{\lfloor{n\over i}\rfloor} gcd(i,j)=d f[d]=i=1∑nj=1∑⌊in⌋gcd(i,j)=d
设 g [ d ] = ∑ i = 1 ⌊ n d ⌋ f [ i d ] g[d]=\sum _{i=1}^{\lfloor{n\over d}\rfloor} f[id] g[d]=i=1∑⌊dn⌋f[id]
反演得
f
[
d
]
=
∑
i
=
1
⌊
n
d
⌋
g
[
i
d
]
∗
μ
(
i
)
f[d]=\sum _{i=1}^{\lfloor{n\over d}\rfloor} g[id]*\mu(i)
f[d]=i=1∑⌊dn⌋g[id]∗μ(i)
a
n
s
=
∑
d
=
1
n
d
∑
i
=
1
⌊
n
d
⌋
g
[
i
d
]
∗
μ
(
i
)
ans=\sum _{d=1}^nd\sum _{i=1}^{\lfloor{n\over d}\rfloor} g[id]*\mu(i)
ans=d=1∑ndi=1∑⌊dn⌋g[id]∗μ(i)
设
T
=
i
d
T=id
T=id,我们发现gcd(i,j)的值不可能大于
n
\sqrt n
n,所以
a
n
s
=
∑
T
=
1
n
g
[
T
]
∗
∑
i
∣
T
T
i
∗
μ
(
i
)
ans=\sum _{T=1}^{\sqrt {n}} g[T]*\sum _{i|T} {T\over i}*\mu(i)
ans=T=1∑ng[T]∗i∣T∑iT∗μ(i)
将
∑
T
=
1
n
∑
i
∣
T
T
i
∗
μ
(
i
)
\sum _{T=1}^{\sqrt n} \sum _{i|T} {T\over i}*\mu(i)
∑T=1n∑i∣TiT∗μ(i)预处理,设为
a
(
i
)
a(i)
a(i)
为了方便预处理,设
i
∗
j
=
T
i*j=T
i∗j=T变形为
a
(
i
)
=
∑
i
=
1
n
∑
i
=
1
⌊
n
d
⌋
j
∗
μ
(
i
)
a(i)=\sum _{i=1}^{\sqrt n} \sum _{i=1}^{\lfloor{\sqrt n\over d}\rfloor} j*\mu(i)
a(i)=i=1∑ni=1∑⌊dn⌋j∗μ(i)
我们知道,如果gcd(x,y)为T的倍数,那么x,y也是T的倍数
那么
x
=
x
′
∗
T
,
y
=
y
′
∗
T
x=x'*T,y=y'*T
x=x′∗T,y=y′∗T
因为
x
∗
y
<
=
n
x*y<=n
x∗y<=n
所以
x
′
x'
x′
枚举
x
′
∗
T
∗
y
′
∗
T
<
=
n
x'*T*y'*T<=n
x′∗T∗y′∗T<=n
所以
g
[
T
]
=
∑
x
=
1
⌊
n
T
2
⌋
⌊
n
T
2
x
⌋
g[T]=\sum _{x=1}^{\lfloor{n\over T^2}\rfloor} \lfloor{n \over T^2x}\rfloor
g[T]=x=1∑⌊T2n⌋⌊T2xn⌋
于是,你会惊奇的发现,答案变成了
a
n
s
=
∑
T
=
1
n
g
[
T
]
∗
a
(
t
)
ans=\sum _{T=1}^{\sqrt n} g[T]*a(t)
ans=T=1∑ng[T]∗a(t)
很简单对吧
但还是过不了
求g[t]的时候用分块优化一下,而t本身不能分块(为什么?)
时间复杂度 O ( n 3 4 ) O(n^{3\over 4}) O(n43)
Code
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define ll long long
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define N 401000
using namespace std;
ll n,mu[N],a[N],bz[N],s[N];
int main()
{
freopen("gcd.in","r",stdin);freopen("gcd.out","w",stdout);
scanf("%lld",&n);
ll m=sqrt(n);
mu[1]=1;
fo(i,2,m)
{
if(!bz[i]) s[++s[0]]=i,mu[i]=-1;
fo(j,1,s[0])
{
int k=i*s[j];
if(k>m) break;
bz[k]=1;
if(i%s[j]==0) {mu[k]=0;break;}
mu[k]=-mu[i];
}
}
fo(i,1,m) fo(j,1,m/i) a[i*j]+=j*mu[i];
ll ans=0;
for(ll t=1;t<=m;t++)
{
ll jy=0,q=n/(t*t);
for(ll x=1,y=1;x<=q;y=x+1,x=min((q/(q/y)),q))
{
jy+=(x-y+1)*(q/x);
if(x>=q) break;
}
ans+=(jy*a[t]);
}
printf("%lld",ans);
}