3505: [Cqoi2014]数三角形
Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 1005 Solved: 616
[Submit][Status][Discuss]
Description
给定一个nxm的网格,请计算三点都在格点上的三角形共有多少个。下图为4x4的网格上的一个三角形。
注意三角形的三点不能共线。
Input
输入一行,包含两个空格分隔的正整数m和n。
Output
输出一个正整数,为所求三角形数量。
Sample Input
2 2
Sample Output
76
数据范围
1<=m,n<=1000
HINT
Source
傻逼题,首先从n*m个点中取3个,再去掉同一条直线上的,分为横竖斜讨论,斜向的应用gcd判断
code:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int read()
{
int x=0,f=1; char ch=getchar();
while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
#define maxn 1010
int n,m;
long long C[maxn*maxn][5];
long long ans;
int gcd(int a,int b)
{
if (b==0) return a; return gcd(b,a%b);
}
void get_C()
{
C[0][0]=1;
for (int i=1; i<=n*m; i++)
{
C[i][0]=1;
for (int j=1; j<=3; j++)
C[i][j]=C[i-1][j-1]+C[i-1][j];
}
}
int main()
{
n=read(),m=read();n++,m++;
get_C();
ans=C[n*m][3]-m*C[n][3]-n*C[m][3];
for (int i=1; i<n; i++)
for (int j=1; j<m; j++)
if (gcd(i,j)>1) ans-=(gcd(i,j)-1)*2*(n-i)*(m-j);
printf("%lld\n",ans);
return 0;
}