题目大意
给定 n , m n,m n,m,求 ∑ i = 1 n ∑ j = 1 m ( ( 2 × i , j ) − 1 ) \sum\limits_{i=1}^n\sum\limits_{j=1}^m\Big((2\times i,j)-1\Big) i=1∑nj=1∑m((2×i,j)−1)
数据范围 1 ⩽ n , m ⩽ 1 0 5 1 \leqslant n, m \leqslant 10^5 1⩽n,m⩽105
题解
原式
=
2
×
∑
i
=
1
n
∑
j
=
1
m
×
(
i
,
j
)
−
n
m
=2\times\sum\limits_{i=1}^n\sum\limits_{j=1}^m\times(i,j)-n m
=2×i=1∑nj=1∑m×(i,j)−nm
因而要点是求
S
=
∑
i
=
1
n
∑
j
=
1
m
×
(
i
,
j
)
S=\sum\limits_{i=1}^n\sum\limits_{j=1}^m\times(i,j)
S=i=1∑nj=1∑m×(i,j)
由
∑
d
∣
n
φ
(
d
)
=
n
∑_{d∣n}φ(d)=n
d∣n∑φ(d)=n
得
S
=
∑
i
=
1
n
∑
j
=
1
m
∑
d
∣
(
i
,
j
)
φ
(
d
)
S=\sum_{i=1}^n\sum_{j=1}^m\sum_{d|(i,j)}φ(d)
S=i=1∑nj=1∑md∣(i,j)∑φ(d)
更换枚举顺序
S
=
∑
i
=
1
n
∑
j
=
1
m
∑
d
=
1
(
i
,
j
)
φ
(
d
)
[
d
∣
(
i
,
j
)
]
S=\sum_{i=1}^n\sum_{j=1}^m\sum_{d=1}^{(i,j)}φ(d)[d|(i,j)]
S=i=1∑nj=1∑md=1∑(i,j)φ(d)[d∣(i,j)]
S = ∑ i = 1 n ∑ j = 1 m ∑ d = 1 ( i , j ) φ ( d ) [ d ∣ i ] [ d ∣ j ] S=\sum_{i=1}^n\sum_{j=1}^m\sum_{d=1}^{(i,j)}φ(d)[d|i][d|j] S=i=1∑nj=1∑md=1∑(i,j)φ(d)[d∣i][d∣j]
各回各家,各找各妈。
S
=
∑
d
=
1
m
i
n
(
n
,
m
)
φ
(
d
)
∑
i
=
1
n
[
d
∣
i
]
∑
j
=
1
m
[
d
∣
j
]
S=\sum_{d=1}^{min(n,m)}φ(d)\sum_{i=1}^n[d|i]\sum_{j=1}^m[d|j]
S=d=1∑min(n,m)φ(d)i=1∑n[d∣i]j=1∑m[d∣j]
化简后面两个和式,得:
S
=
∑
d
=
1
m
i
n
(
n
,
m
)
φ
(
d
)
⌊
n
d
⌋
⌊
m
d
⌋
S=\sum_{d=1}^{min(n,m)}φ(d)\Big\lfloor\frac{n}{d}\Big\rfloor\Big\lfloor\frac{m}{d}\Big\rfloor
S=d=1∑min(n,m)φ(d)⌊dn⌋⌊dm⌋
线性筛便是 Θ ( m i n ( n , m ) ) \Theta(min(n,m)) Θ(min(n,m)),因而可以不用除法分块,代码记得开long long。
代码
#include<bits/stdc++.h>
using namespace std;
#define maxn 100010
int prime[maxn],phi[maxn];
bool vis[maxn];
void euler_phi(int n){
memset(phi,0,sizeof phi);
memset(vis,0,sizeof vis);
int tot=0;phi[1]=1;
for(int i=2;i<=n;i++){
if(!vis[i]){
prime[++tot]=i;
phi[i]=i-1;
}
for(int j=1;j<=tot&&i*prime[j]<=n;j++){
vis[i*prime[j]]=1;
if(i%prime[j]==0){
phi[i*prime[j]]=phi[i]*prime[j];
break;
} phi[i*prime[j]]=phi[i]*(prime[j]-1);
}
}
}
int main(){
int n,m;
scanf("%d%d",&n,&m);
int l=min(n,m);
long long ans=0;
euler_phi(l);
for(int i=1;i<=l;i++)
ans+=(long long)phi[i]*(n/i)*(m/i);
printf("%lld\n",2*ans-(long long)n*m);
return 0;
}