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