#include #include #include #include #include #define REP(i,a,b) for(i=a;i=3 && k%2) continue; rep(i,k){ if((k-i)%2) B[k] += Comb[k+1][i] * B[i]; else B[k] -= Comb[k+1][i] * B[i]; } B[k] /= k+1; } } double HarmonicNumber(ll n){ double x=n, gamma=0.57721566490153286060651209008240243104215933593992; if(n<100000) return Hmemo[n]; return gamma + log(x) + 1.0/2/x - 1.0/12/x/x + 1.0/120/x/x/x/x; } double pw(double a, ll b){ double res; if(b==0) return 1; res = pw(a, b/2); res = res*res; if(b%2) res = res*a; return res; } /* solve1, solve2, solve3 calculate T(N,P) = (1/N)^P + (2/N)^P + ... + (N/N)^P solveb1, solveb2, solveb3 calculate T(N,P) - T(N,P+1) solve1, solveb1, solve2, solveb2 assume P >= N/2, and (k/N)^P are ignore for small k. solve2, solveb2 also assume N > 10^9, and (1-1/N)^N ~ exp(-1) is used, because (1-1/N) has a little error, and (1-1/N)^N may have a big error (if it is calculated by ordinary ways). In solve1 and solveb1 (for N < 10^9), usual pow function is used. solve3, solveb3 assume N > 2P and use Faulhaber's formula. In solveb1, solveb2, solveb3 some tricks are used for avoiding the cancellation of significant digits. */ double solve1(ll N, ll P){ ll i, j, k; double res = 0, per, pp, bef, aft; double rest = 1; bef = 1; rep(i,N){ if(bef < 1e-11 || i>=10){ res += (i+1)*bef; break; } per = (N-i-1) / (double)N; aft = pw(per, P); pp = bef - aft; bef = aft; res += (i+1) * pp; } return res; } double solve2(ll N, ll P){ ll i, j, k; double res = 0, per, pp, bef, aft, mul; double rest = 1; bef = 1; mul = exp(-P/(double)N); rep(i,N){ if(bef < 1e-11 || i>=10){ res += (i+1)*bef; break; } aft = bef * mul; pp = bef - aft; bef = aft; res += (i+1) * pp; } return res; } double solve3(ll N, ll P){ ll i; double res = 0, mul = N; rep(i,P+1){ res += B[i] * mul; mul /= N; mul /= i+1; mul *= P+1-i; if(mul < 1e-100) break; if(i>=11) break; } res /= P+1; return res; } double solveb1(ll N, ll P){ ll i, j, k; double res = 0, per, po; double rest = 1; rep(i,N){ if(i>=10) break; per = (N-i-1) / (double)N; po = pw(per, P); res += po * (i+1) / N; } return res; } double solveb2(ll N, ll P){ ll i, j, k; double res = 0, per, po, mul; double rest = 1; per = 1; mul = exp(-P/(double)N); rep(i,N){ if(i>=10) break; per *= mul; res += per * (i+1) / N; } return res; } double solveb3(ll N, ll P){ ll i; double res = 0; double mul = N / (double)(P+1) / (double)(P+2); res += B[0] * mul; mul = - 0.5 / N; REP(i,2,P+1){ res += B[i] * mul * (i-1); mul /= N; mul /= i+1; mul *= P-i+2; if(-mul < 1e-40) break; if(i>=15) break; } return res; } /* calculate the expected time */ double solveG(ll N, ll P, double S, double T){ double res = S * HarmonicNumber(P-1); if(N > P/2) res += T * solve3(N, P); else if(N < 1000000000) res += T * solve1(N, P); else res += T * solve2(N, P); return res; } /* calculate solve*(N, P) - solve*(N, P+1) without cancellation of significant digits! */ /* where solve*(N, P) = (1/N)^P + (2/N)^P + ... + (N/N)^P */ double solveB(ll N, ll P){ double res = 0; if(N > P/2) res += solveb3(N, P); else if(N < 1000000000) res += solveb1(N, P); else res += solveb2(N, P); return res; } double solveT(ll N, ll P, double S, double T){ ll i, P1, P2, G, opt; double t1, t2, t, c; c = S / T; if( N==1 || (N - 1.0/N)/6.0 < c ) return T*(N+1)/2; /* use 1 computer */ P1 = 1; P2 = P; /* binary search for determining the number of using computers */ while(P1 < P2){ G = (P1 + P2)/2; t = G * solveB(N, G); if(t > c) P1 = G+1; else P2 = G; } return solveG(N, P1, S, T); /* calculate the expected time */ } int main(){ int i,j,k; int TEST, C_SUM = 0; int C, K; ll N[2100], P[2100], t; double V, X[2100], S[2100], T[2100]; double res, tmp; double cost[21][2100]; double dp[40]; Initialization(); assert(scanf("%d",&TEST)==1); while(TEST--){ assert(scanf("%d%d%lf",&C,&K,&V)==3); assert(1<=C&&C<=1000 && 1<=K&&K<=5&&K<=C && 1<=V&&V<=1e20); rep(i,K) assert(scanf("%lld",N+i)==1), assert(1LL<=N[i]&&N[i]<=1000000000000000000LL); rep(j,C){ assert(scanf("%lld%lf%lf%lf",P+j,S+j,T+j,X+j)==4); assert(1LL<=P[j] && P[j]<=1000000000000000000LL); assert(1<=S[j]&&S[j]<=1e20 && 1<=T[j]&&T[j] <=1e20 && -1e20<=X[j]&&X[j]<=1e20); } C_SUM += C; assert(C_SUM <= 5000); /* sort: X[0] <= X[1] <= ... */ rep(i,C) REP(j,1,C) if(X[j-1] > X[j]){ t = P[j-1]; P[j-1] = P[j]; P[j] = t; tmp = X[j-1]; X[j-1] = X[j]; X[j] = tmp; tmp = S[j-1]; S[j-1] = S[j]; S[j] = tmp; tmp = T[j-1]; T[j-1] = T[j]; T[j] = tmp; } /* calculate the expected time for cracking the i-th piece in the j-th computer center */ rep(i,K) rep(j,C) cost[i][j] = solveT(N[i], P[j], S[j], T[j]); /* do DP */ res = 1e200; rep(i,1<=0;i--) rep(k,K) if(!(i&1< tmp) dp[i+(1< 0) tmp += X[j] * 2 / V; /* most right computer center */ if(res > tmp) res = tmp; } printf("%.10f\n",res); } return 0; }