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;}

完结撒花

 

posted @ 2018-10-15 14:55  ASDIC减除  阅读(139)  评论(0编辑  收藏  举报