codeforces 317 A - Lengthening Sticks
来源:互联网 发布:淘宝母婴店图片装修 编辑:程序博客网 时间:2024/05/16 12:57
题目描述:
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.
题解:
很好地一道题目。给出以下解法。
(1)最笨最麻烦的解法:我们认定a是最的边,其他的<=a.那么我们暴力枚举a+x的x,设b+i,那么i的定义域我们知道了.对于一个i,c的可取范围其实是一个一次函数,但是这个一次函数是分段的.所以我们要耐心的解出一个有定义域且分段的一次函数.很麻烦,可以用很多if,也可以合起来写.之后是容斥的部分,很简单,暴力就好.
(2)思考一点反面:当我们认定a是最大的边的时候,b和c算反面。那么都有什么反面?b大于a,c大于a,b和c都小于等于a,但是b+c<=a. 前一部分用容斥,后一部分是重点:在三角形中很常用的技巧.b+c<=a,那么自然而然的b<=a,c<=a.这样就做了.
(3)整体思考反面.很好的思维:首先笨笨的算出所有的情况.之后减去不合法的:不合法的中,我们认定a是这种情况下最大的.那么,此时b和c已经天然有了<=a的性质,只需要减去b+c<=a的情况.之后我们容斥,a和b同样都是最大的,c比较小,这种情况没有不合法情况,abc都最大也没有不合法情况.所以就结束了.
重点:
(1)三角形判定,认定一条边是最大值.之后的只需要b+c>a就好了.
(2)解法一中的用函数表示对函数求和的方法.
(3)逆向思维.特别是三角形判定有一个最大边什么的.
(4)容斥的掌握,减去的东西应该是上一步大前提下多算的.
代码:
//三种解法都写在下面了#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <cmath>#include <ctype.h>#include <limits.h>#include <cstdlib>#include <algorithm>#include <vector>#include <queue>#include <map>#include <stack>#include <set>#include <bitset>#define CLR(a) memset(a, 0, sizeof(a))#define REP(i, a, b) for(ll i = a;i < b;i++)#define REP_D(i, a, b) for(ll i = a;i <= b;i++)typedef long long ll;using namespace std;const double EPS = 1e-9;ll a, b, c, s;ll gao(ll a, ll b, ll xl, ll xr){ if(xl > xr) return 0; if(a*xl + b < 0 && a*xr+b<0) return 0; double key = -b*1.0/a; ll keyx; if(a > 0) { keyx = (key - EPS); keyx++; } else { keyx = (key + EPS); } if(a*xl + b < 0) { xl = keyx; } if(a*xr + b < 0) { xr = keyx; } ll ans = b*(xr-xl+1); ll tmp = (xr+xl)*(xr-xl+1)/2; ans += tmp*a; return ans;}ll first_old(ll a, ll b, ll c){ ll ans = 0; ll i1, i2; ll jl, jr; ll tmp, oldAns; for(ll x = 0; x<=s; x++) { tmp = 0; oldAns = ans; ll keyi = min(a+x-b, s - x); if(keyi < 0) continue; i1 = a+x+1-b-c; i2 = s-2*x-a+c; i1 = min(keyi, i1); i2 = min(keyi, i2); if(i1 < 0 && i2 < 0) { jl = 0; jr = keyi; ans += gao(-1, s-x+1, jl, jr); } else if(i1 < 0) { jl = 0; jr = i2; ans += gao(0, a+x-c+1, jl, jr); jl = i2+1; jr = keyi; ans += gao(-1, s-x+1, jl, jr); } else if(i2 < 0) { jl = 0; jr = i1; ans += gao(0, s - 2*x - a - 1 + b +c+1, jl, jr); jl = i1+1; jr = keyi; ans += gao(-1, s-x+1, jl, jr); } else { if(i1==i2) { jl = 0; jr = i1; ans += gao(1, b-1+1, jl, jr); jl = i1+1; jr = keyi; ans += gao(-1, s-x+1, jl, jr); } else if(i1 < i2) { jl = 0; jr = i1; ans += gao(1, b-1+1, jl, jr); jl = i1+1; jr = i2; ans += gao(0, a+x-c+1, jl, jr); jl = i2+1; jr = keyi; ans += gao(-1, s-x+1, jl, jr); } else { jl = 0; jr = i2; ans += gao(1, b-1+1, jl, jr); jl = i2+1; jr = i1; ans += gao(0, s - 2*x - a - 1 + b +c+1, jl, jr); jl = i1+1; jr = keyi; ans += gao(-1, s-x+1, jl, jr); } }// for(ll bx = 0;bx+x<=s;bx++)// {// for(ll cx = 0;cx+bx+x<=s;cx++)// {// if(a+x >= b+bx && a+x >= c+cx)// {// if(a+x+b+bx>c+cx && a+x+c+cx>b+bx && b+bx+c+cx>a+x)// {// tmp++;// }// }// }// } //printf("x is %I64d ans is %I64d tmp is %I64d\n", x, ans - oldAns, tmp); } return ans;}ll first(ll a, ll b, ll c){ ll ans = 0; for(ll x = 0; x<=s; x++) { if(b > a+x || c > a+x) continue; ll tmp = (s - x + 2)*(s-x + 1)/2; if(s-x-(a+x+1-b) >= 0) tmp -= (s-x-(a+x+1-b)+2)*(s-x-(a+x+1-b)+1)/2; if(s-x-(a+x+1-c) >= 0) tmp -= (s-x-(a+x+1-c)+2)*(s-x-(a+x+1-c)+1)/2; if(s - x - (a+x+1-b) - (a+x+1-c)>=0) { tmp += (s - x - (a+x+1-b) - (a+x+1-c)+2)*(s - x - (a+x+1-b) - (a+x+1-c)+1)/2; } ll sum = a+x - b - c; if(sum >= 0) { sum = min(sum, s - x); tmp -= (sum+2)*(sum+1)/2; } ans += tmp;// ll tmp2 = 0;// for(ll bx = 0; bx+x<=s; bx++)// {// for(ll cx = 0; cx+bx+x<=s; cx++)// {// if(a+x >= b+bx && a+x >= c+cx)// {// if(a+x+b+bx>c+cx && a+x+c+cx>b+bx && b+bx+c+cx>a+x)// {// tmp2++;// }// }// }// }// printf("x is %I64d ans is %I64d tmp is %I64d\n", x, tmp, tmp2); } return ans;}ll second(ll a, ll b, ll c){ ll ans = 0; for(ll i = max(a, b);; i++) { if(i < c) continue; ll t = i - a + i - b; t = s - t; if(t < 0) break; if(c + t > i) { ans += i-c+1; } else { ans += t+1; } } return ans;}ll third(ll a, ll b, ll c){ ll ans = 0; ll t = max(a, b); t = max(t, c); for(ll i = t;; i++) { ll used = 3*i - a - b - c; if(used > s) break; ans++; } return ans;}void solve_old(){ ll ans = 0; ans += first(a, b, c); ans += first(b, a, c); ans += first(c, a, b); ans -= second(a, b, c); ans -= second(b, c, a); ans -= second(a, c, b); ans += third(a, b, c); printf("%I64d\n", ans);}ll new_first(ll a, ll b, ll c){ ll ans = 0; for(ll x = 0;x<=s;x++) { if(a+x-b-c<0) continue; ll tmp = min(a+x-b-c, s-x); ans += (tmp+2)*(tmp+1)/2; } return ans;}ll new_second(ll a, ll b, ll c){ ll ans = 0; for(ll x = max(a, b);;x++) { if(x-a+x-b > s) break; ll tmp = s - (x-a+x-b); if(2*x-c>0) tmp -= (2*x-c); if(tmp >= 0) ans += tmp+1; } return ans;}void solve(){ ll ans = (s+3)*(s+2)*(s+1)/6; ans -= new_first(a, b, c); ans -= new_first(b, a, c); ans -= new_first(c, a, b); //ans += new_second(a, b, c); //ans += new_second(b, c, a); //ans += new_second(a, c, b); printf("%I64d\n", ans);}int main(){ freopen("1Ain.txt", "r", stdin); //freopen("1Aout.txt", "w", stdout); while(scanf("%I64d%I64d%I64d%I64d", &a, &b, &c, &s) != EOF) { solve(); } return 0;}
- codeforces 317 A - Lengthening Sticks
- Codeforces Round #317 A.Lengthening Sticks
- codeforces 571 A Lengthening Sticks
- Lengthening Sticks - Codeforces 571 A
- codeforces 571 A. Lengthening Sticks
- Codeforces Round #317 A. Lengthening Sticks(组合+容斥)
- 容斥 + 组合数学 ---Codeforces Round #317 A. Lengthening Sticks
- [组合] Codeforces #571A. Lengthening Sticks
- Lengthening Sticks CodeForces
- 571A Lengthening Sticks
- Codeforces Round #317 [AimFund Thanks-Round] (Div. 1) A. Lengthening Sticks 分类
- Codeforces Round #317 (Div. 2) 571A. Lengthening Sticks 组合数学
- codeforces 571A--Lengthening Sticks(组合+容斥)
- 【codeforces 572C】Lengthening Sticks
- CodeForces #317 (div2) C.Lengthening Sticks (容斥)
- C. Lengthening Sticks(Codeforces Round #317 容斥定理)
- codeforces #317 C. Lengthening Sticks (很好的想法题)
- cf Div#317 Lengthening Sticks
- 算法导论—红黑树
- jquery ajax json struts2 action中的方法执行了两次
- ios 播放声音文件
- 大牛们推荐的VC++的学习网址
- 引导页
- codeforces 317 A - Lengthening Sticks
- gcc 编译多个源文件
- Java 的 interface、abstract class 与 C++ 的多继承、虚基类
- 【Django】优化小技巧之清除过期session
- Android:AsyncTask -- 异步任务
- LINQ语句中的.AsEnumerable() 和 .AsQueryable()的区别
- 互联网文摘
- popwindow在View的上,下,左,右 显示
- json(map)与xml的转化