TCO14286 TriangleTriples

题目链接: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 \times B \times 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 };

 

  
posted @ 2018-06-13 16:31  Blogggggg  阅读(231)  评论(0编辑  收藏  举报