Codeforces Round #317 [AimFund Thanks-Round] (Div. 1)(组合数学+容斥)

来源:互联网 发布:网页游戏发布平台源码 编辑:程序博客网 时间:2024/05/30 04:46

A. Lengthening Sticks

You are given three sticks with positive integer lengths of a, b, and c centimeters. You can increase length of some of them by some positive integer number of centimeters (different sticks can be increased by a different length), but in total by at most l centimeters. In particular, it is allowed not to increase the length of any stick.

Determine the number of ways to increase the lengths of some sticks so that you can form from them a non-degenerate (that is, having a positive area) triangle. Two ways are considered different, if the length of some stick is increased by different number of centimeters in them.

Input

The single line contains 4 integers a, b, c, l (1 ≤ a, b, c ≤ 3·105, 0 ≤ l ≤ 3·105).

Output

Print a single integer — the number of ways to increase the sizes of the sticks by the total of at most l centimeters, so that you can make a non-degenerate triangle from it.
Sample test(s)
Input

1 1 1 2

Output

4

Input

1 2 3 1

Output

2

Input

10 2 1 7

Output

0

Note

In the first sample test you can either not increase any stick or increase any two sticks by 1 centimeter.

In the second sample test you can increase either the first or the second stick by one centimeter. Note that the triangle made from the initial sticks is degenerate and thus, doesn’t meet the conditions.

思路:转自组合数学+容斥
1.求全部组合的情况:
当L=0时,res=1;
当L=1时,res=3;所以当L=1时形成的情况为1+3=4
当L=2时,res=6;所以当L=2时形成的情况为4+6=10
当L=3时,res=10; 所以当L=3时形成的情况为10+10=20
……..
所以由上面可以推出当L=n时,全部的组合情况是C(n+3,3)。
2.不符合三角形定理的情况:
如果要形成一个三角形,那么必须任意两边之和大于第三边。那么不符合的就是任意一边大于等于其余两边的和。所以分别把a,b,c当成第三边,然后再考虑将剩下的l拆分三份分配给a,b,c依旧不满足的情况即可。
我们先把a当成第三边,然后给a增加一个La,现在i=a+La,Max=a+b+c+L。现在我们考虑b+c的范围,因为是不满足的情况,所以b+c的变化范围<=i,又因为总长度Max的限制,b+c<=Max-i,所以b+c的最大变化范围只能在min(i,Max-i)。令x=min(i,Max-i)-b-c表示总共变化量的大小,即Lb+Lc<=x,等价于tmp+Lb+Lc的方案数。

那为什么是C(n+3,3)那,可以把它分成四部分,然后第一部分表示多余的,然后用公式Cnn+r1算出来就行了

#include<bits/stdc++.h>using namespace std;typedef long long LL;LL a,b,c,l;LL cal(LL x,LL y,LL z,LL l){    LL ans=0;    for(LL i=x;i<=x+l;i++){        if(y+z>i)continue;        LL tmp=min(i,x+y+z+l-i)-y-z;        ans+=(tmp+1)*(tmp+2)/2;    }    return ans;}int main(){    cin>>a>>b>>c>>l;    LL ans=(l+3)*(l+2)*(l+1)/6;    ans-=cal(a,b,c,l);    ans-=cal(c,b,a,l);    ans-=cal(b,a,c,l);    cout<<ans<<endl;    return 0;}
0 0