浴谷国庆集训 D2提高模拟测试1 Massacre at Béziers

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浴谷国庆集训 D2提高模拟测试1 Massacre at Béziers相关的知识,希望对你有一定的参考价值。

题目

题目描述

我妻蛤乃给你出了一道送命题:

黄梅时节家家雨,青草池塘处处蛙~

有n只青蛙,第i只青蛙会每过xi秒会连续叫yi秒。然而由于青蛙的寿命在增加,所以从第二次开始每次休息结束后这只青蛙连续叫的时间会增加zi秒。

给定n只青蛙,每一只的xi,yi,zi,以及时间t,求在前t秒中,所有青蛙共叫了多少秒。

输入输出格式

输入格式:

第一行两个数n和t之后n行,第i+1行每行三个非负整数xi,yi,zi

输出格式:

一行一个数表示答案

输入输出样例

输入样例#1:

8 10
9 1 1
1 9 9
4 1 0
2 3 3
1 0 0
1 4 0
9 2 5
1 2 1

输出样例#1:

34

输入样例#2:

1 233333
233 233 233

输出样例#2:

223081

输入样例#3:

10 100000000
1 0 0
1 0 5
1 2 2
1 2 8
1 3 0
1 5 0
1 5 2
1 5 5
1 7 0
1 8 3

输出样例#3:

845787522

说明

样例#4,#5见下发的文件

【子任务】

子任务会给出部分测试数据的特点。 如果你在解决题目中遇到了困难, 可以尝试只解决一部分测试数据。

每个测试点的数据规模及特点如下表:

技术分享

对于100%的数据,n <= 100000 , t <= 2000000000,x + y + z > 0

0 <= x , y , z <= 2000000000

【说明】

【样例1说明】

每只青蛙分别叫了1,9,2,6,0,8,1,7秒

【样例2说明】

那只青蛙叫了223081秒

【样例3说明】

每只青蛙分别叫了0,99993675,99990000,99994999,75000000,83333333,99990002,99993676,87500000,99991837秒

思路:

第一题看似是一道水题。/假的

最后写得这个方法呢,是利用二分答案算青蛙叫的次数,然后用 t 减去。
注意:

  1. 二分的时候两个 2e9 加起来会爆掉 int 的……
  2. 如果这个青蛙叫的时间会增长,那么二分的上界是 O(sqrt(t)) 级别的。
 1 #include <iostream>
 2 #include <cstdlib>
 3 #include <cstdio>
 4 #include <algorithm>
 5 #include <cstring>
 6 #include <cmath>
 7 using namespace std;
 8 unsigned int n,t;
 9 long long ans;
10 inline long long cal( long long x , long long y , long long z , long long k )
11 {
12     return k * 1ll * ( x + y ) + k * 1ll * ( k + 1 ) / 2 * z;
13 }
14 inline long long cal()
15 {
16     long long x  , y , z  , l = 1 , r = t , ans = 0 , mid;
17     cin >> x >> y >> z;
18     if( z ) r = sqrt( 2 * t / z ) + 233333/*忽略它*/;
19     y -= z;
20     while( l <= r )
21     {
22         mid = (l + r) >> 1;
23         if(mid * 1ll * ( x + y ) + mid * 1ll * ( mid + 1 ) / 2 * z <= t)
24         {
25             l = mid + 1;
26             ans = mid;
27         }
28         else 
29             r = mid - 1;
30     }
31     return ans * 1ll * x + min(t-cal(x,y,z,ans),1ll*x);
32 //
33 }
34 int main()
35 {
36     //freopen("test.in","r",stdin);
37     //freopen("test.out","w",stdout);
38     cin >> n >> t;
39     for (unsigned int i=1; i<=n; i++)
40     {
41         int thisFrog = cal();
42         //cout << thisFrog << endl;
43         ans += t-thisFrog;
44     }
45     cout << ans << endl;
46     return 0;
47 }

 


以上是关于浴谷国庆集训 D2提高模拟测试1 Massacre at Béziers的主要内容,如果未能解决你的问题,请参考以下文章

国庆集训模拟赛总结

10.2 正睿国庆集训测试1

2017 10 1国庆培训七天总结(提高组),第一天(STL)。

国庆集训数论总结

国庆七天乐LeetCode算法14天集训营题解(1~7天)

2019牛客国庆集训派对day3 排列(状压dp)