首先会发现直接算很难算
那么就考虑计算三点共线的方案吧
由于两直角边分别为 a,b 的三角形,斜边上整点数为 gcd(a,b)+1
然后中间点要共线就只有 gcd(a,b)−1 种可能
然后把斜边遍历整个网格图 (n−a+1)⋅(n−b+1)
最后注意一下这个斜边是可以对称翻转的
示例程序:
#include<cstdio>
typedef long long ll;
int n,m,nm;
ll ans;
ll gcd(int x,int y){
return y==0?x:gcd(y,x%y);
}
int main(){
scanf("%d%d",&n,&m);nm=(n+1)*(m+1);
ans=(ll)nm*(nm-1)*(nm-2)/6;
for (int i=0;i<=n;i++)
for (int j=0;j<=m;j++)
if (i||j){
ll s=(gcd(i,j)-1)*(n-i+1)*(m-j+1);
ans-=s*((i&&j)?2:1);
}
printf("%lld",ans);
return 0;
}