容斥一下。
题目要求
∑i=1n∑j=1mgcd(i,j)∗2−1
因为i和j限制不同,所以不能用那种线性筛的方法啦。
我们可以考虑用 f(x) 表示 gcd(i,j)=x 的个数,这个并不好求。那么我们考虑用 g(x) 表示 x 为
那么着里边就存在一些约数为 2d,3d,4d... 的数对 (i,j) ,我们要把它减去。
所以
f(x)=g(x)−∑j=2,j∗x<=min(n,m)f(j∗x)
然后倒序就好啦。
#include<iostream>
#include<cstdio>
#define ll long long
using namespace std;
ll ans,f[100005];
int n,m;
int main()
{
scanf("%d%d",&n,&m);
if (n>m) swap(n,m);
for (int i=n;i;i--)
{
f[i]=(ll)(m/i)*(n/i);
for (int j=2;j*i<=n;j++)
f[i]-=f[i*j];
ans+=f[i]*(2*i-1);
}
cout << ans << endl;
return 0;
}