传送门
取等是因为最优解法一定把能量用完,需要满足:
那么直接二分
#include<bits/stdc++.h>
#define
#define
using namespace std;
cs double eps = 1e-12;
cs int N = 1e4 + 50;
int n; double E, s[N], k[N], v[N], a[N];
double sqr(double a){ return a * a; }
double clc(double v, double v0, double k){ return k*v*v*(v-v0)*2; }
double chk(double lambda){
double sm=0;
for(int i=1; i<=n; i++){
double l=max(0.0,v[i]), r=1e5;
while(r-l>eps){
double mid=(l+r)/2;
if(lambda*clc(mid,v[i],k[i])>=1) r=mid; else l=mid;
} a[i]=l; sm=sm+k[i]*sqr(a[i]-v[i])*s[i];
} return sm;
}
double work(){ double as=0; for(int i=1; i<=n; i++) as=as+s[i]/a[i]; return as; }
int main(){
scanf("%d%lf",&n,&E);
for(int i=1; i<=n; i++)
scanf("%lf%lf%lf",&s[i],&k[i],&v[i]);
double l=0, r=1e5;
while(r-l>eps){
double mid=(l+r)/2;
if(chk(mid)>E) l=mid; else r=mid;
} printf("%.8lf",work()); return 0;
}