极其简单的一道题,求一下组合数再算一下gcd即可
一开始错是因为未考虑到除了(0,0)到(x,y)矩形平移还会产生平行的对角线。
后来乘上平移的数量,又发现只枚举矩形右下角的点并在对角线上采用组合数会出错,因为平移所乘的数和组合数会有大量重复,改成枚举矩形的左上和右下两个端点就好了,剩下一个点的数量即是对角线上点数-2。
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
int n,m;
long long c[4][1005];
void chart()
{
c[0][0]=1;
for(int i=1;i<=1002;i++)
{
c[0][i]=1;
for(int j=1;j<=3;j++)
c[j][i]=c[j-1][i-1]+c[j][i-1];
}
}
int getgcd(int x,int y)
{
if(!y)return x;
return getgcd(y,x%y);
}
int main()
{
scanf("%d%d",&n,&m);
n++,m++;
chart();
int point=n*m;
long long ans=1LL*point*(point-1)*(point-2)/6;
ans-=1LL*m*c[3][n];
ans-=1LL*n*c[3][m];
for(int i=1;i<n;i++)
for(int j=1;j<m;j++)
{
int gcd=getgcd(i,j);
if(gcd>=2)
ans-=1LL*(gcd-1)*2*(n-i)*(m-j);
}
printf("%lld",ans);
return 0;
}