inline LL power(LL x, int p){ LL cnt = 1; while (p) { if (p & 1) cnt = cnt * x % MOD; x = x * x % MOD, p >>= 1; } return cnt; }
int T, N, M, D; int a[MAXN]= {0};
LL inv[MAXD]= {0}; LL fact[MAXD]= {0}, ifact[MAXD]= {0}; inline LL C(int n, int m){ if (m > n) return0; return fact[n] * ifact[m] % MOD * ifact[n - m] % MOD; }
LL f[MAXD][MAX]= {0}, g[MAXN][MAXD]= {0}; inlineintlowbit(int x){ return x & (- x); } inlineintcalc(int state){ int cnt = 0; while (state > 0) { cnt ++; state ^= lowbit (state); } return cnt; }
int b[MAXN]= {0};
inlineintgetnum(){ int num = 0; char ch = getchar (); while (! isdigit (ch)) ch = getchar (); while (isdigit (ch)) num = (num << 3) + (num << 1) + ch - '0', ch = getchar (); return num; }
intmain(){ N = getnum (), M = getnum (), D = getnum (); T = N + M; fact[0] = ifact[0] = 1; fact[1] = ifact[1] = inv[1] = 1; for (int i = 2; i <= max (T, D); i ++) { fact[i] = fact[i - 1] * i % MOD; inv[i] = (MOD - MOD / i) * inv[MOD % i] % MOD; ifact[i] = ifact[i - 1] * inv[i] % MOD; } int tot = 0; for (int i = 1; i <= N + M; i ++) { a[i] = getnum (); tot += a[i]; } D = min (D, tot); int limit = (1 << T) - 1; f[0][0] = 1; for (int i = 0; i < D; i ++) for (int state = 0; state <= limit; state ++) { int s = calc (state), sum = 0; for (int j = 1; j <= T; j ++) if (state & (1 << (j - 1))) sum += a[j]; if (i < sum) continue; f[i + 1][state] = (f[i + 1][state] + f[i][state] * inv[T - s] % MOD) % MOD; for (int k = 1; k <= T; k ++) if (! (state & (1 << (k - 1)))) { LL mul = C (i - sum, a[k] - 1) % MOD * inv[T - s] % MOD; f[i + 1][state | (1 << (k - 1))] = (f[i + 1][state | (1 << (k - 1))] + f[i][state] * mul % MOD) % MOD; } } int stan = 0; LL ans = 0; for (int j = N + 1; j <= T; j ++) stan |= (1 << (j - 1)); for (int state = 0; state <= limit; state ++) if ((state & stan) == stan) { int sum = 0, m = 0; g[0][0] = 1; for (int j = 1; j <= T; j ++) { if (state & (1 << (j - 1))) sum += a[j]; else b[++ m] = a[j]; } int V = D - sum; for (int j = 1; j <= m; j ++) for (int k = 0; k <= V; k ++) { g[j][k] = 0; for (int l = 0; l <= min (k, b[j] - 1); l ++) g[j][k] = (g[j][k] + g[j - 1][k - l] * C (V - (k - l), l) % MOD) % MOD; } ans = (ans + f[D][state] * g[m][V] % MOD) % MOD; } cout << ans << endl;
inlineintdcmp(Ld p){ if (fabs (p) < eps) return0; return p < 0 ? - 1 : 1; }
int T; int t[MAXN][MAXN]= {0}; int cnt[MAXN]= {0}; Ld zero[MAXN][MAXN]= {0}; Ld value(int n, Ld val){ Ld x = 1, ret = 0; for (int i = 0; i <= n; i ++, x = x * val) ret += t[n][i] * x; return ret; } boolfind(int n, Ld L, Ld R, Ld& ze){ int d1 = dcmp (value (n, L)); int d2 = dcmp (value (n, R)); if (d1 * d2 > 0) returnfalse; if (d1 * d2 == 0) { ze = d1 == 0 ? L : R; returntrue; } if (d1 < 0) { Ld left = L, right = R; while (dcmp (right - left) > 0) { Ld mid = (left + right) / 2.0; if (dcmp (value (n, mid)) <= 0) left = mid; else right = mid; } ze = left; } else { Ld left = L, right = R; while (dcmp (right - left) > 0) { Ld mid = (left + right) / 2.0; if (dcmp (value (n, mid)) >= 0) left = mid; else right = mid; } ze = left; } returntrue; } voidwork(int n){ if (n == 1) { Ld a = t[n][1], b = t[n][0]; zero[n][++ cnt[n]] = - b / a; return ; } if (n == 2) { Ld a = t[n][2], b = t[n][1], c = t[n][0]; Ld delta = b * b - 4 * a * c; if (dcmp (delta) < 0) return ; elseif (dcmp (delta) >= 0) { if (dcmp (delta) == 0) delta = 0; Ld x1, x2; if (dcmp (a) > 0) { x1 = (- b - sqrt (delta)) / (2.0 * a); x2 = (- b + sqrt (delta)) / (2.0 * a); } else { x1 = (- b + sqrt (delta)) / (2.0 * a); x2 = (- b - sqrt (delta)) / (2.0 * a); } if (dcmp (delta) == 0) zero[n][++ cnt[n]] = x1; else { zero[n][++ cnt[n]] = x1; zero[n][++ cnt[n]] = x2; } } return ; } work (n - 1); if (! cnt[n - 1]) { Ld posi; if (find (n, - INF, INF, posi)) zero[n][++ cnt[n]] = posi; return ; } zero[n - 1][0] = - INF, zero[n - 1][cnt[n - 1] + 1] = INF; for (int i = 0; i <= cnt[n - 1]; i ++) { Ld posi; if (find (n, zero[n - 1][i], zero[n - 1][i + 1], posi)) zero[n][++ cnt[n]] = posi; } } voidsolve(int n){ for (int i = n - 1; i >= 0; i --) for (int j = 0; j <= i; j ++) t[i][j] = t[i + 1][j + 1] * (j + 1); work (n); printf ("%d\n", cnt[n]); for (int i = 1; i <= cnt[n]; i ++) printf ("%.8Lf\n", zero[n][i]); }
inlineintgetnum(){ int num = 0; char ch = getchar (); bool isneg = false; while (! isdigit (ch)) { if (ch == '-') isneg = true; ch = getchar (); } while (isdigit (ch)) num = (num << 3) + (num << 1) + ch - '0', ch = getchar (); return isneg ? - num : num; }
intmain(){ T = getnum (); for (int Case = 1; Case <= T; Case ++) { memset (t, 0, sizeof (t)); memset (cnt, 0, sizeof (cnt)); memset (zero, 0, sizeof (zero)); int n = getnum (); for (int i = 0; i <= n; i ++) t[n][i] = getnum (); solve (n); }
structLFS {int to, next; } ; LFS Link[MAXM << 1]; int Head[MAXN]= {0}, size = 0; voidInsert(int u, int v){ Link[++ size].to = v; Link[size].next = Head[u];
Head[u] = size; }
int N, M, E = 0, Tm; int b[MAXN]; int f[MAXN], c[MAXN], w[MAXN]; vector<int> G[MAXN]; vector<int> pt[MAXN], ex[60]; int poi[MAXN]= {0}, pex[MAXN]= {0}; int ances[MAXN]; intfind(int x){ return ances[x] == x ? x : ances[x] = find (ances[x]); } pair<int, int> edge[MAXM]; voidbuild(){ for (int i = 1; i <= N; i ++) ances[i] = i; for (int i = 1; i <= M; i ++) { int x = edge[i].first, y = edge[i].second; int fx = find (x), fy = find (y); if (fx == fy) { b[++ E] = x; continue; } ances[fx] = fy; Insert (x, y), Insert (y, x); } }
bool visit[MAXN]= {false}; int subsize[MAXN], g, mini; voidacsize(int root, int father, int n){ subsize[root] = 1; int maxpart = 0; for (int i = Head[root]; i; i = Link[i].next) { int v = Link[i].to; if (v == father || visit[v]) continue; acsize (v, root, n); subsize[root] += subsize[v]; maxpart = max (maxpart, subsize[v]); } maxpart = max (maxpart, n - subsize[root]); if (maxpart < mini) g = root, mini = maxpart; } int lev[MAXN]= {0}; int depth[25][MAXN], d[MAXN], m = 0, mdep = 0; voidDFS(int root, int father, int l){ d[++ m] = root; mdep = max (mdep, depth[l][root]); for (int i = Head[root]; i; i = Link[i].next) { int v = Link[i].to; if (v == father || visit[v]) continue; depth[l][v] = depth[l][root] + 1; DFS (v, root, l); } } int father[MAXN]= {0}; int buck[MAXN]= {0}, topo[MAXN]; voiddivide(int u, int n, int l, int fa){ mini = INF, acsize (u, 0, n); father[g] = fa; visit[g] = true; mdep = m = 0, lev[g] = l, depth[l][g] = 0; DFS (g, 0, l); for (int i = 0; i <= mdep; i ++) buck[i] = 0; for (int i = 1; i <= m; i ++) buck[depth[l][d[i]]] ++, topo[i] = 0; for (int i = 1; i <= mdep; i ++) buck[i] += buck[i - 1]; for (int i = 1; i <= m; i ++) topo[buck[depth[l][d[i]]] --] = d[i]; for (int i = 1; i <= m; i ++) pt[g].push_back(topo[i]); acsize (g, 0, n); int fg = g; for (int i = Head[fg]; i; i = Link[i].next) { int v = Link[i].to; if (visit[v]) continue; divide (v, subsize[v], l + 1, fg); } } bool vis[MAXN]= {false}; queue<int> que; int deep[51][MAXN]= {0}; voidlinkit(int S, int id){ while (! que.empty()) que.pop(); memset (vis, false, sizeof (vis)); que.push(S), deep[id][S] = 0, vis[S] = true; while (! que.empty()) { int u = que.front(); que.pop(); for (int i = 0; i < (int) G[u].size(); i ++) { int v = G[u][i]; if (vis[v]) continue; deep[id][v] = deep[id][u] + 1; que.push(v); vis[v] = true; } } for (int i = 0; i <= N; i ++) buck[i] = topo[i] = 0; for (int i = 1; i <= N; i ++) buck[deep[id][i]] ++; for (int i = 1; i <= N; i ++) buck[i] += buck[i - 1]; for (int i = 1; i <= N; i ++) topo[buck[deep[id][i]] --] = i; for (int i = 1; i <= N; i ++) ex[id].push_back(topo[i]); } LL value[MAXN], ans[MAXN]= {0}, dist[MAXN]; structnode { int id; LL d; node (int id = 0, LL d = 0) : id (id), d (d) {} booloperator < (const node& p) const { return d > p.d; } } ; priority_queue<node> heap; voidtrans(int u, LL d){ for (int p = u; p; p = father[p]) { int l = lev[p]; for ( ; poi[p] < (int) pt[p].size(); poi[p] ++) { int v = pt[p][poi[p]]; if (depth[l][u] + depth[l][v] > f[u]) break; if (dist[v] < LINF) continue; dist[v] = dist[u] + value[v]; heap.push(node (v, dist[v])); } } for (int i = 1; i <= E; i ++) { for ( ; pex[i] < (int) ex[i].size(); pex[i] ++) { int v = ex[i][pex[i]]; if (deep[i][u] + deep[i][v] > f[u]) break; if (dist[v] < LINF) continue; dist[v] = dist[u] + value[v]; heap.push(node (v, dist[v])); } } } voidsolve(int T){ for (int i = 1; i <= N; i ++) value[i] = 1ll * c[i] * T + w[i]; memset (poi, 0, sizeof (poi)); memset (pex, 0, sizeof (pex)); while (! heap.empty()) heap.pop(); memset (dist, 0x3f, sizeof (dist)); dist[1] = value[1], heap.push(node (1, dist[1])); while (! heap.empty()) { node top = heap.top(); heap.pop(); int u = top.id; LL d = top.d; trans (u, d); } for (int i = 1; i <= N; i ++) ans[i] = min (ans[i], dist[i] - value[i]); }
inlineintgetnum(){ int num = 0; char ch = getchar (); bool isneg = false; while (! isdigit (ch)) { if (ch == '-') isneg = true; ch = getchar (); } while (isdigit (ch)) num = (num << 3) + (num << 1) + ch - '0', ch = getchar (); return isneg ? - num : num; } inlinevoidwrite(LL x){ if (x >= 10) write (x / 10); putchar (x % 10 + '0'); }
intmain(){ N = getnum (), M = getnum (), Tm = getnum (); for (int i = 1; i <= N; i ++) f[i] = getnum (), c[i] = getnum (), w[i] = getnum (); for (int i = 1; i <= M; i ++) { int u = getnum (), v = getnum (); G[u].push_back(v), G[v].push_back(u); edge[i] = make_pair (u, v); } build (); sort (b + 1, b + E + 1); E = unique (b + 1, b + E + 1) - b - 1; divide (1, N, 1, 0); for (int i = 1; i <= E; i ++) linkit (b[i], i); memset (ans, 0x3f, sizeof (ans)); solve (1), solve (Tm); for (int i = 1; i <= N; i ++) write (ans[i]), puts ("");