1. 程式人生 > >【BZOJ3505】[Cqoi2014]數三角形 組合數

【BZOJ3505】[Cqoi2014]數三角形 組合數

namespace space long sca light names -a 註意 i++

【BZOJ3505】[Cqoi2014]數三角形

Description

給定一個nxm的網格,請計算三點都在格點上的三角形共有多少個。下圖為4x4的網格上的一個三角形。

註意三角形的三點不能共線。

Input

輸入一行,包含兩個空格分隔的正整數m和n。

Output

輸出一個正整數,為所求三角形數量。

Sample Input

2 2

Sample Output

76
數據範圍
1<=m,n<=1000

題解:顯然要用補集法,我們只需要求出三點共線的方案數即可。方法是先枚舉兩端的點所形成的向量,然後線段中間的點的個數就是gcd(x,y)。

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
int m,n;
ll ans;
int gcd(int a,int b)	{return (!b)?a:gcd(b,a%b);}
ll c3(int x)	{return (ll)x*(x-1)*(x-2)/6;}
int main()
{
	scanf("%d%d",&n,&m);
	int i,j,g;
	for(i=1;i<=n;i++)	for(j=1;j<=m;j++)
	{
		g=gcd(i,j);
		ans+=(ll)(n-i+1)*(m-j+1)*(g-1);
	}
	ans=c3((n+1)*(m+1))-ans*2-(m+1)*c3(n+1)-(n+1)*c3(m+1);
	printf("%lld",ans);
	return 0;
}

【BZOJ3505】[Cqoi2014]數三角形 組合數