题解 速通
是出题人没学过语文还是我没学过语文(恼
写出的转移中需要与 \(f_{1, 0}\) 取 \(\min\)
那么二分这个东西的取值即可
p.s. 第五个包数据假了,不满足特殊性质
点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 100010
#define pb push_back
#define ll long long
//#define int long long
int n, lim;
double p[N];
int l[N], r[N];
vector<int> e[N];
namespace task1{
bool g[110][1010];
struct line{double k, b; line():k(0),b(0){} line(double x, double y):k(x),b(y){}}f[110][1010];
inline line operator + (line a, line b) {return {a.k+b.k, a.b+b.b};}
inline line operator * (line a, double t) {return {a.k*t, a.b*t};}
inline bool isable(int i, int j) {return j<=lim?g[i][j]:0;}
void dfs1(int u) {
if (!e[u].size()) {
for (int i=0; i<=lim; ++i) g[u][i]=1;
return ;
}
for (auto v:e[u]) dfs1(v);
for (int j=0; j<=lim; ++j)
for (auto v:e[u]) if (p[v]>0)
g[u][j]|=isable(v, j+l[v]);
}
void dfs2(int u) {
// cout<<"dfs2: "<<u<<endl;
for (auto v:e[u]) dfs2(v);
for (int j=0; j<=lim; ++j) {
// cout<<"j: "<<j<<endl;
for (int k=l[u]; k<=r[u]; ++k) {
// cout<<"k: "<<k<<endl;
if (isable(u, j+k)) {
line sum;
for (auto v:e[u]) sum=sum+f[v][j+k]*p[v];
sum=sum+line(0, k);
// cout<<"("<<sum.k<<' '<<sum.b<<") "<<endl;
f[u][j]=f[u][j]+sum;
}
else f[u][j]=f[u][j]+line(1, k);
}
f[u][j]=f[u][j]*(1.0/(r[u]-l[u]+1.0));
}
}
void solve() {
dfs1(1); dfs2(1);
// cout<<"("<<f[1][0].k<<' '<<f[1][0].b<<") "<<endl;
if (!isable(1, 0)) puts("Remake");
else {
double ans=f[1][0].b/(1-f[1][0].k);
if (ans>=1e9) puts("Remake");
else printf("%.10lf\n", ans);
}
}
}
namespace task{
double f[110][2010];
void solve() {
double l=0, r=1e9+1, mid;
for (int t=1; t<=60; ++t) {
mid=(l+r)/2;
// cout<<"mid: "<<mid<<endl;
memset(f, 0x43, sizeof(f));
for (int i=n; i; --i) {
// cout<<"i: "<<i<<endl;
for (int j=0; j<=lim; ++j) {
// cout<<"j: "<<j<<endl;
double sum=0;
for (int k=::l[i]; k<=::r[i]; ++k) {
// cout<<"k: "<<k<<endl;
if (j+k<=lim) {
double tem=0;
for (auto v:e[i]) tem+=p[v]*f[v][j+k];
// cout<<"tem: "<<tem<<endl;
sum+=min(tem, mid)+k;
}
else sum+=mid+k;
}
f[i][j]=sum/(::r[i]-::l[i]+1);
}
}
if (f[1][0]>mid) l=mid;
else r=mid;
}
if (l>=1e9) puts("Remake");
else printf("%.10lf\n", l);
}
}
signed main()
{
freopen("isaac.in", "r", stdin);
freopen("isaac.out", "w", stdout);
scanf("%d%d", &n, &lim);
for (int i=1; i<=n; ++i) scanf("%d%d", &l[i], &r[i]);
for (int i=2,f; i<=n; ++i) scanf("%d%lf", &f, &p[i]), e[f].pb(i);
// task1::solve();
task::solve();
return 0;
}