$\huge \color{orange}{成魔之路->}$ $\huge \color{purple}{算法提高课题解}$
思路:
1. 首先 n ++,m ++,转换为格点数
2. 总方案:C(n * m, 3)
3. 横线:n * C(m, 3)
4. 竖线:m * C(n, 3)
5. 斜线:(gcd(i, j) - 1) * (n - i)(m - j) (i, j) = (纵坐标之差,横坐标之差)
6. 合法方案 = C(n * m, 3) - n * C(m, 3) - m * C(n, 3) - (gcd(i, j) - 1) * (n - i)(m - j)
完整代码
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
LL C(int n)
{
return (LL)n*(n-1)*(n-2)/6;
}
int gcd(int a,int b)
{
return b?gcd(b,a%b):a;
}
int main()
{
int n,m;
cin>>n>>m;
n++,m++;
LL res=C(n*m)-(LL)n*C(m)-(LL)m*C(n);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
res-=2*(gcd(i,j)-1)*(n-i)*(m-j);
cout<<res<<endl;
return 0;
}