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

 

posted @ 2017-02-16 09:02  Candy?  阅读(213)  评论(0编辑  收藏  举报