给定长度为 N N 的数组 ,求
∑1≤i≤n,1≤j≤ma[gcd(i,j)]
∑
1
≤
i
≤
n
,
1
≤
j
≤
m
a
[
g
c
d
(
i
,
j
)
]
数据范围: 1≤n,m≤N≤105 1 ≤ n , m ≤ N ≤ 10 5 。
设
f(n,m)=∑i=1n∑j=1ma[gcd(i,j)]=∑d=1min(n,m)∑i=1n∑j=1ma[d]×[gcd(i,j)==d]=∑d=1min(n,m)a[d]×∑i=1nd∑j=1md[gcd(i,j)==1]
f
(
n
,
m
)
=
∑
i
=
1
n
∑
j
=
1
m
a
[
g
c
d
(
i
,
j
)
]
=
∑
d
=
1
m
i
n
(
n
,
m
)
∑
i
=
1
n
∑
j
=
1
m
a
[
d
]
×
[
g
c
d
(
i
,
j
)
==
d
]
=
∑
d
=
1
m
i
n
(
n
,
m
)
a
[
d
]
×
∑
i
=
1
n
d
∑
j
=
1
m
d
[
g
c
d
(
i
,
j
)
==
1
]
先知道莫比乌斯函数的定义:
∑d|nμ(d)=1 (当n=1)∑d|nμ(d)=0 (当n>1)
∑
d
|
n
μ
(
d
)
=
1
(
当
n
=
1
)
∑
d
|
n
μ
(
d
)
=
0
(
当
n
>
1
)
设
g(n,m)=∑i=1n∑j=1m[gcd(i,j)==1]=∑i=1n∑j=1m∑d|gcd(i,j)μ(d)=∑d=1min(n,m)μ(d)×nd×md
g
(
n
,
m
)
=
∑
i
=
1
n
∑
j
=
1
m
[
g
c
d
(
i
,
j
)
==
1
]
=
∑
i
=
1
n
∑
j
=
1
m
∑
d
|
g
c
d
(
i
,
j
)
μ
(
d
)
=
∑
d
=
1
m
i
n
(
n
,
m
)
μ
(
d
)
×
n
d
×
m
d
则
f(n,m)=∑d=1min(n,m)a[d]×g(nd,md)
f
(
n
,
m
)
=
∑
d
=
1
m
i
n
(
n
,
m
)
a
[
d
]
×
g
(
n
d
,
m
d
)
复杂度计算: ∑ni=1ni≈O(nlogn) ∑ i = 1 n n i ≈ O ( n l o g n )
美团的笔试题给定了A数组,即
a1=p,ai=(ai+153)%p
a
1
=
p
,
a
i
=
(
a
i
+
153
)
%
p
。
代码如下:
#include <bits/stdc++.h>
using namespace std;
int a[100007],mu[100007];
using ll = long long;
ll g(int n, int m)
{
ll ret = 0;
for(int i=1; i<=min(n, m); ++i)
ret+=(ll)mu[i]*(n/i)*(m/i);
return ret;
}
int main()
{
int N,n,m,p;
scanf("%d%d%d%d",&N,&n,&m,&p);
ll ans = 0;
mu[1]=1;
for(int i=1; i<=N; ++i)
for(int j=2*i;j<=N;j+=i)
mu[j]-=mu[i];
a[1]=p;
for(int i=2; i<=N; ++i)
a[i]=(a[i-1]+153)%p;
for(int i=1; i<=min(n, m); ++i)
{
ans+=(ll)a[i]*g(n/i,m/i);
}
cout << ans << '\n';
return 0;
}