Kotori is practicing making fireworks for the upcoming hanabi taikai1. It takes her nn minutes to make a single firework, and as she is not really proficient in making fireworks, each firework only has a probability of p \times 10^{-4}p×10
−4
to be perfect.

After she finishes making a firework, she can just start making the next firework, or take mm minutes to light all the remaining fireworks finished before. If there is at least one perfect firework among the lit ones, she will be happy and go to rest. Otherwise, she will continue practicing. Can you tell her the minimum expected practicing time before she goes to rest if she takes the optimal strategy?

Notice that no matter how many fireworks remain, it always takes mm minutes to light them all.

1Hanabi taikai: Romaji of the Japanese word “花火大會”, which means the firework… err… party?

There are multiple test cases. The first line of the input contains an integer TT (1 \le T \le 10^41≤T≤10

4
) indicating the number of test cases. For each test case:The first and only line contains three integers nn, mm and pp (1 \le n, m \le 10^91≤n,m≤10
9
, 1 \le p \le 10^41≤p≤10
4
).

For each test case, output one line containing one number indicating the minimum expected practicing time.

Your answer will be considered correct if and only if the absolute or relative error does not exceed 10^{-4}10
−4
.

3
1 1 5000
1 1 1
1 2 10000

4.0000000000
10141.5852891136
3.0000000000

### 1、F Fireworks

• 制作一个烟花需要n分钟，成功的概率为p。完成一次制作后可以继续制作或花m分钟点燃之前所有的烟花，如果有一个烟花是成功的，那么就可以开始休息。
• 求最小的期望开始休息时间（即期望的最早成功制作一个烟花的时间）

• 因为每次都是做出来一批集中释放做好的看看有没有成功的，所以不妨设最优策略为每次做k个能最早休息。所以问题转化为每次制作k个释放，期望的最早制作成功的时间。
• 每轮制作耗费时间kn+m，至少一个烟花制作成功的概率为，所以根据几何分布公式可以得到期望为
• 对该式子打表或者求二阶导可以发现这是个单峰的凹函数。可以三分答案。
#include<bits/stdc++.h>
using namespace std;
typedef long double LD;
LD fun(int k, int n, int m, LD p){
return ((LD)k*n+m)/((LD)1.0-pow(1.0-p,k));
}
int main(){
int T;  cin>>T;
while(T--){
int n, m;  LD p;
cin>>n>>m>>p;
p *= (1e-4);
int l = 1, r = 1e9+10;
while(l < r){
int mid1 = l+(r-l)/3, mid2 = r-(r-l)/3;
if(fun(mid1,n,m,p)<fun(mid2,n,m,p))r = mid2-1;
else l = mid1+1;
}
printf("%.10Lf\n", fun(l,n,m,p));
}
return 0;
}

• 什么是凹函数？
• 什么是三分？
二分查找 适用于单调函数中逼近求解某点的值。
三分查找可以用于求凹凸函数的那个凸点或凹点