BZOJ 3505: [Cqoi2014]数三角形 [组合计数]

3505: [Cqoi2014]数三角形

给定一个nxm的网格,请计算三点都在格点上的三角形共有多少个。

注意三角形的三点不能共线。

1<=m,n<=1000


$n++ m++$

$ans={nmchoose 3}-n*{mchoose 3}-m*{nchoose 3}-斜线上的情况$

n和m很小,我们直接枚举以(0,0)为左端点的斜线,以两端点为两个点,中间的第三个点有$(x,y)-1$种选择,然后乘上平移的方案数再乘以2,斜线还有反向

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
inline int read(){
    char c=getchar();int x=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
ll n,m,ans;
int gcd(int a,int b){return b==0?a:gcd(b,a%b);}
int main(){
    n=read()+1;m=read()+1;
    ll x=n*m;
    ans+=x*(x-1)*(x-2)/6; 
    ans-=m*n*(n-1)*(n-2)/6+n*m*(m-1)*(m-2)/6;
    for(int i=1;i<n;i++)
        for(int j=1;j<m;j++)
            ans-=(n-i)*(m-j)*(gcd(i,j)-1)<<1;
    printf("%lld",ans);
}
原文地址:https://www.cnblogs.com/candy99/p/6404189.html