Description
求解 2∗i=1∑Nj=1∑Mgcd(i,j)−N∗M
做这道题前可以先看看 仪仗队 .
正解部分
首先说一下为什么求解的是上方的式子,
对一个点 (x,y), 遮拦这个点的个数为 gcd(x,y)−1, 又因为一个点的贡献为 2(gcd(x,y)−1)+1, 所以可以得到上式 .
重点为下方这个式子:
i=1∑Nj=1∑Mgcd(i,j)
解法 1:
容斥原理
考虑枚举 d, 统计有多少 (i,j) 满足 gcd(i,j)=d,
以 d 为约数的点对数为 ⌊dN⌋⌊dM⌋ ,
只需将 d 不是最小公倍数的点对数减去就行了, 具体 容斥 过程见代码 .
时间复杂度 O(NlogN)
#include<cstdio>
#include<algorithm>
#define reg register
typedef long long ll;
const int maxn = 100005;
int N;
int M;
ll Ans;
ll cnt[maxn];
int main(){
scanf("%d%d", &N, &M);
for(reg int d = std::min(N, M); d >= 1; d --){
cnt[d] = (1ll*M/d) * 1ll*(N/d);
for(reg int j = 2; j*d <= std::min(N, M); j ++) cnt[d] -= cnt[j*d];
Ans += (d*2 - 1) * cnt[d];
}
printf("%lld\n", Ans);
return 0;
}
解法 2:
欧拉反演
存在这个等式 ↓
d∣N∑φ(d)=N
如果不懂请点击 这里
将 N 换为 gcd(i,j), 原式变为 ↓
i=1∑Nj=1∑Md∣gcd(i,j)∑φ(d)
d=1∑Nφ(d)⌊dN⌋⌊dM⌋
代码略 .