版权声明:本博客中有原创标签的内容均为博主原创,转载请注明出处! https://blog.csdn.net/lleozhang/article/details/83416791
非常好的题
简化一下题意,我们可以发现:(0,0)与(x,y)之间经过的整点的数量等于gcd(x,y)-1!
利用这条性质,我们可以列出一个表达式:
稍微化简一下,得:
接下来,是最重要的一部分:
引理:
那么,将x=gcd(i,j)代入,得:
再化简一下,得:
由于n,m很小,所以预处理出φ,然后暴力枚举计算即可
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#define ll long long
#define maxn 1000000
using namespace std;
int phi[1000005];
int pri[1000005];
bool used[1000005];
int n,m;
int tot=0;
void init()
{
phi[1]=1;
for(int i=2;i<=maxn;i++)
{
if(!used[i])
{
pri[++tot]=i;
phi[i]=i-1;
}
for(int j=1;j<=tot&&i*pri[j]<=maxn;j++)
{
used[i*pri[j]]=1;
if(i%pri[j]==0)
{
phi[i*pri[j]]=phi[i]*pri[j];
break;
}else
{
phi[i*pri[j]]=phi[i]*(pri[j]-1);
}
}
}
}
int main()
{
init();
scanf("%d%d",&n,&m);
ll ans=0;
for(int i=1;i<=min(n,m);i++)
{
ans+=(ll)phi[i]*(ll)(n/i)*(ll)(m/i);
}
ans*=2ll;
ans-=(ll)n*(ll)m;
printf("%lld\n",ans);
return 0;
}