C. Lengthening Sticks
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output
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.
Examples
input
Copy
1 1 1 2
output
Copy
4
input
Copy
1 2 3 1
output
Copy
2
input
Copy
10 2 1 7
output
Copy
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.
题意:
有三个长度为abc的棍子,可以给这三个棍子增加边长,总共增加的边长不超过l,问你可以组成合法的三角形多少个
思路 :
很好的组合数学问题,我们考虑用l所有的分配情况-拼出的不合法的三角形的情况
首先所有的情况就是在l个位置里放三个插板,但是可以放在相同的位置,所以每次你插入一个板子,这个板子都可以变成位置,所以就是c(3,n + 3)
假如a是最大边 a + l' >= b + c(这是不符合的情况)
那剩下的l - l'就是分给b和c的,所以就是a + l' >= b + c + (l - l'),假设x = (l - l')
x <= a + l' - b - c,所以问题现在来到了怎么把x分给b和c,问最后b和c有多少种方案,因为b和c可以都不分,所以是
1+2+3+...+x+1种,那么我们枚举l就可以解决了
代码:
#include <bits/stdc++.h>
#include <time.h>
#define fi first
#define se second
#define endll "\n"
#define MS0(X) memset((X), 0, sizeof((X)))
#define MS1(X) memset((X), -1, sizeof((X)))
#define LEN(X) strlen(X)
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)
#define rg(a,x,y) (a+x), (a+y+1)
#define vrg(a,x,y) (a.begin()+x),(a.begin()+y+1)
#define all(x) (x).begin(),(x).end()
#define rall(x) (x).rbegin(),(x).rend()
#define _sum(a) accumulate(a, 0ll)
#define pb push_back
#define pr make_pair
#define bugc(_) cerr << (#_) << " = " << (_) << endl;
///vector(len,val);
using namespace std;
typedef long long ll;
typedef double db;
int xx[4] = {1,-1,0,0};
int yy[4] = {0,0,1,-1};
const double eps = 1e-9;
typedef pair<int,int> P;
const int maxn = 2e6 + 5000;
const ll mod = 1e9 + 7;
const int INF(0x3f3f3f3f);
const ll INFL(0x3f3f3f3f3f3f3f3fll);
inline int sign(db a) { return a < -eps ? -1 : a > eps;}
//inline int cmp(db a,db b){ return sign(a - b);}
ll mul(ll a,ll b,ll c) { ll res = 1; while(b) { if(b & 1) res *= a,res %= c; a *= a,a %= c,b >>= 1; } return res;}
ll phi(ll x) { ll res = x; for(ll i = 2; i * i <= x; i++) { if(x % i == 0) res = res / i * (i - 1); while(x % i == 0) x /= i; } if(x > 1) res = res / x * (x - 1); return res;}
template <typename A, typename B> inline bool chmin(A &a, B b){if(a > b) {a = b; return 1;} return 0;}
template <typename A, typename B> inline bool chmax(A &a, B b){if(a < b) {a = b; return 1;} return 0;}
template <typename A, typename B> inline ll add(A x, B y) {if(x + y < 0) return x + y + mod; return x + y >= mod ? x + y - mod : x + y;}
template <typename A, typename B> inline void add2(A &x, B y) {if(x + y < 0) x = x + y + mod; else x = (x + y >= mod ? x + y - mod : x + y);}
template <typename A, typename B> inline ll mul1(A x, B y) {return 1ll * x * y % mod;} /// x * y % mod;
template <typename A, typename B> inline void mul2(A &x, B y) {x = (1ll * x * y % mod + mod) % mod;} /// return x * y
template <typename A> inline void debug(A a){cout << a << '\n';}
template <typename A> inline ll sqr(A x){return 1ll * x * x;}
template <typename A> A inv(A x) {return mul(x, mod - 2);}
template<class T>void wt(const T& x){cout << x << endl;}
template<class T>void wt(const T& x, char c){cout << x << c;}
template<class T>void wt(const T& x, const string& s){cout << x << s;}
template<class T>void wt(const T& x, int rnd){
cout << fixed << setprecision(rnd) << x << endl;}
inline void debug(){ cout << "###!!!" << endl;}
inline ll read() { char c = getchar(); ll x = 0, f = 1; while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}while(c >= '0' && c <= '9') x = 1ll * x * 10 + c - '0', c = getchar();return x * f;}
int fa[maxn];
int Find(int x) { if(x != fa[x]) return fa[x] = Find(fa[x]); return fa[x];}
ll n,k,m;
ll ans = 0,sum = 0;
//a + i - b - c >= x;
ll solve(ll x){///calc(x);
// cout << x << endl;
if(x < 0) return 0;
return (x + 1) * (x + 2) / 2ll;
}
int main() {
ll a,b,c,l;
ios::sync_with_stdio(false);
while(cin >> a >> b >> c >> l){
sum = 0,ans = (l + 1) * (l + 2) * (l + 3) / 6;
// cout << ans << endl;
for(int i = 0;i <= l;i++){
// cout << a << " " << b << " " << c << " " << l << endl;
sum += solve(min(l - i,a - b - c + i));
// cout << sum << endl;
sum += solve(min(l - i,b - a - c + i));
// cout << sum << endl;
sum += solve(min(l - i,c - a - b + i));
// cout << sum << endl;
}
cout << ans - sum <<endl;
}
}