题目链接:https://vjudge.net/problem/TopCoder-14286
知识点: 组合数学、容斥原理
题目大意:
给出 (A,B,C),问有多少个有序三元组 ((a,b,c)),满足 (a le A,b le B,c le C),并且长度为 (a,b,c) 的三条边能构成三角形。输出答案数模 (1000000007) 后的值。
(A,B,C le 10^9).
解题思路:
答案等于 (A imes B imes C) 减去不能构成三角形的方案数。有三种不能构成三角形的对称的情况:
(a+b le c, a+c le b, b+c le a).
现在先求解 (a+b le c) 的情况,其他两种情况做类似处理即可。已知 (c le C)。可以将 (a +b le c) 表达成 (a+b+x=c, 0 le x),将 (c le C) 表达成 (c+y=C, 0 le y)。则我们可以列出下式:
(a+b+x+y=C, 1 le a,b, 0 le x,y)
上式的解的个数即为满足 (a+b le c) 的方案数,等价于将 (C) 分成 (4) 份(允许其中有两份为 (0))的方案数再利用容斥原理减去 (a>A, b>B) 的部分,具体的式子是
(C_{C+1}^{3}-C_{C-A+1}^{3}-C_{C-B+1}^{3}+C_{C-A-B+1}^{3}).
AC代码:
1 #include <cstdio> 2 3 using namespace std; 4 typedef long long LL; 5 const LL mod=1e9+7; 6 7 class TriangleTriples{ 8 public: 9 LL c3(LL a){ 10 if(a<3) return 0; 11 return a*(a-1)%mod*(a-2)%mod*166666668%mod; 12 } 13 LL solve(LL a,LL b,LL c){ 14 return (c3(a+1)-c3(a-b+1)-c3(a-c+1)+c3(a-b-c+1)+mod)%mod; 15 } 16 17 int count(int A, int B, int C){ 18 LL a=A,b=B,c=C; 19 LL ans=a*b%mod*c%mod; 20 ans=(ans-solve(a,b,c)-solve(b,a,c)-solve(c,a,b))%mod; 21 ans+=mod; 22 ans%=mod; 23 return (int)ans; 24 } 25 };