voidfft(cp *a, int n, cp *omg){ for (int i = 0; i < n; ++i) if (i < rev[i]) std::swap(a[i], a[rev[i]]); for (int l = 2; l <= n; l <<= 1) { int m = l / 2; for (int i = 0; i < n; i += l) { for (int j = 0; j < m; ++j) { auto tmp = a[i + j + m] * omg[n / l * j]; a[i + j + m] = a[i + j] - tmp; a[i + j] = a[i + j] + tmp; } } } }
voidclear(){ for (int i = 0; i < len; ++i) a[i] = b[i] = omg[i] = inv[i] = {0, 0}, rev[i] = 0; n = m = c = len = 0; }
voidset(int _n, int _m){ n = _n, m = _m; }
voidmul(){ prework(); fft(a, len, omg), fft(b, len, omg); for (int i = 0; i < len; ++i) a[i] = a[i] * b[i]; fft(a, len, inv); for (int i = 0; i < len; ++i) a[i].a /= len; } } // namespace FFT
voidsolve(int l, int r){ if (l == r) { for (int i = 1; i < n; ++i) f[i][l] = 1e18; for (int i = 1; i <= m; ++i) if (u[i] != n) f[u[i]][l] = std::min(f[u[i]][l], g[i][l] + w[i]); return; } int mid = (l + r) >> 1; if (r - l + 1 != 2 * t) solve(mid + 1, r); for (int i = 1; i <= m; ++i) { if (u[i] == n) continue; FFT::set(r - l, r - mid); for (int j = 1; j <= r - l; ++j) FFT::a[j] = {p[i][j], 0}; for (int j = 1; j <= r - mid; ++j) FFT::b[j] = {f[v[i]][r - j + 1], 0}; FFT::mul(); for (int j = r - mid + 1; j <= r - l + 1; ++j) { g[i][r - j + 1] += FFT::a[j].a; } FFT::clear(); } solve(l, mid); }
voiddickdreamer(){ std::cin >> n >> m >> t >> x; for (int i = 1; i <= n; ++i) for (int j = 1; j <= n; ++j) dis[i][j] = (i != j) * 1e18; for (int i = 1; i <= m; ++i) { std::cin >> u[i] >> v[i] >> w[i]; dis[u[i]][v[i]] = w[i]; for (int j = 1; j <= t; ++j) { int x; std::cin >> x; p[i][j] = x / 1e5; } } for (int k = 1; k <= n; ++k) for (int i = 1; i <= n; ++i) for (int j = 1; j <= n; ++j) dis[i][j] = std::min(dis[i][j], dis[i][k] + dis[k][j]); for (int i = 0; i < 2 * t; ++i) f[n][i] = x * (i > t); for (int i = 1; i < n; ++i) for (int j = t; j < 2 * t; ++j) f[i][j] = x + dis[i][n]; solve(0, 2 * t - 1); std::cout << std::fixed << std::setprecision(10) << f[1][0] << '\n'; }