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.
The single line contains 4 integers a, b, c, l (1 ≤ a, b, c ≤ 3·105, 0 ≤ l ≤ 3·105).
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.
1 1 1 2
4
1 2 3 1
2
10 2 1 7
0
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.
当时做的时候怎么想都是n平方的做法,原来还可以容斥,顾名思义,先全部考虑,再去除不符合条件的,有中学时学排列组合的思想。
先算C(L+3,3),然后枚举每个边作为最长边(达不到最长就补),逐渐加i,使另外两边之和小于这条边,则另外两条边可使用长度为min(L-i,a-b-c)(因为b+c不能大于a嘛),
枚举时i可能从0或者b+c-a开始。
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<stack>
#include<cstring>
#include<string>
#include<vector>
#include<cmath>
#include<map>
using namespace std;
typedef long long ll;
#define mem(a,b) memset(a,b,sizeof(a))
const int maxn = 5e5+5;
const int ff = 0x3f3f3f3f;
const double esp = 1e-7;
ll a,b,c,l;
ll ans;
ll exc(ll x,ll y,ll z,ll len)
{
ll sum = 0;
for(ll i = max((ll)0,y+z-x);i<= len;i++)
{
ll tmp = min(len-i,x+i-y-z)+2;
sum+= (tmp-1)*tmp/2;
}
return sum;
}
int main()
{
cin>>a>>b>>c>>l;
ans = (l+3)*(l+2)*(l+1) / 6;
ans-= exc(a,b,c,l);
ans-= exc(b,a,c,l);
ans-= exc(c,a,b,l);
cout<<ans<<endl;
return 0;
}