luogu 3166 组合与gcd(数三角形)结论
在n*m的点格图中选取三个点满足三角形的个数
结论:点(x1,y1)和(x2,y2) 中间有gcd(x2-x1,y2-y1)+1个和两点连成的线段直线共线
那么大力枚举 x2-x1和y2-y1,然后发现满足这个条件的实际上可以看作是一个矩形,那么矩形所有能够平移的位置就是它所有能够满足的答案,
注意:共有左下—右上,左上—右下,两种情况,可以在枚举时aabs,但是十分麻烦,所以不如直接 *2,
注意点格图的n,m均是格子而非点,n++,m++;
#include<bits/stdc++.h> #define int long long using namespace std; int m,n,ans; inline int C(int n){ return n*(n-1)*(n-2)/6;} inline int gcd(int x,int y){ while(y){int tmp=x%y;x=y;y=tmp;}return x;} #undef int int main(){ #define int long long scanf("%d%d",&m,&n);m++;n++; ans=C(n*m); if(n>=3) ans-=C(n)*m; if(m>=3) ans-=C(m)*n; for(int i=1;i<n;i++) for(int j=1;j<m;j++) ans-=(n-i)*(m-j)*(gcd(i,j)-1)*2; printf("%lld\n",ans);return 0;}
完结撒花