【bzoj3505】[Cqoi2014]数三角形 容斥原理

题目描述

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

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

输入

输入一行,包含两个空格分隔的正整数m和n。

输出

输出一个正整数,为所求三角形数量。

样例输入

2 2

样例输出

76


题解

容斥原理

三角形数目=选出三个点的方案数-三点共线的方案数。

选出三个点的方案数显然为$C_{(n+1)(m+1)}^3$。

三线共线的方案数,考虑枚举两端点,统计出一个矩形内的方案数,再算出总体方案数。其中点坐标的gcd-1为中间点的个数。

#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long ll;
ll gcd(ll a , ll b)
{
	return b ? gcd(b , a % b) : a;
}
int main()
{
	ll n , m , i , j , t , ans;
	scanf("%lld%lld" , &n , &m) , t = (n + 1) * (m + 1);
	ans = t * (t - 1) * (t - 2) / 6;
	for(i = 0 ; i <= n ; i ++ )
	{
		for(j = 0 ; j <= m ; j ++ )
		{
			t = gcd(i , j) - 1;
			if(t <= 0) continue;
			t *= (n - i + 1) * (m - j + 1);
			if(i && j) ans -= t << 1;
			else ans -= t;
		}
	}
	printf("%lld\n" , ans);
	return 0;
}

 

 

posted @ 2017-08-15 20:06  GXZlegend  阅读(440)  评论(0编辑  收藏  举报