BZOJ 3505: [Cqoi2014]数三角形 [组合计数]
3505: [Cqoi2014]数三角形
给定一个nxm的网格,请计算三点都在格点上的三角形共有多少个。
注意三角形的三点不能共线。
1<=m,n<=1000
$n++ m++$
$ans={nm\choose 3}-n*{m\choose 3}-m*{n\choose 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); }
Copyright:http://www.cnblogs.com/candy99/