1 条题解
-
0

#include <bits/stdc++.h> #define lg2(x) (31 - __builtin_clz(x)) const int MP = 530000; typedef int vec[MP], *pvec; typedef long long ll; const ll mod = 998244353, pmod = mod - 1, half_mod = (mod + 1) / 2, root = 31; const int N = 100054; int n, C; vec fact, inv, finv; inline int & reduce(int &x) {return x += (x >> 31 & (int)mod);} inline ll & half(ll &x) {return x = (x >> 1) + (-(x & 1) & half_mod);} ll PowerMod(ll a, int n, ll c = 1) {for (n %= pmod, n += n >> 31 & pmod, a %= mod; n; n >>= 1, a = a * a % mod) if (n & 1) c = c * a % mod; return c;} void init(int n) { int i; for (inv[1] = 1, i = 2; i <= n; ++i) inv[i] = (mod - mod / i) * inv[mod % i] % mod; for (*finv = *fact = i = 1; i <= n; ++i) fact[i] = (ll)fact[i - 1] * i % mod, finv[i] = (ll)finv[i - 1] * inv[i] % mod; } struct edge { int u, v; edge (int u0 = 0, int v0 = 0) : u(u0), v(v0) {} edge * read() {scanf("%d%d", &u, &v); if (u > v) std::swap(u, v); return this;} inline bool operator < (const edge &B) const {return u < B.u || (u == B.u && v < B.v);} inline bool operator == (const edge &B) const {return u == B.u && v == B.v;} }; namespace Subtask1 { edge e[N], f[N]; int main() { int i, j, g = n; for (i = 1; i < n; ++i) e[i].read(); std::sort(e + 1, e + n); for (i = 1; i < n; ++i) f[i].read(); std::sort(f + 1, f + n); for (j = i = 1; i < n; g -= f[j] == e[i++]) for (; j < n && f[j] < e[i]; ++j); return printf("%lld\n", PowerMod(C, g)), 0; } } namespace Subtask2 { edge e[N * 2]; int E = 0, first[N], next[N * 2]; int w, f[N], g[N]; inline void addedge(int u, int v) { e[++E] = edge(u, v); next[E] = first[u]; first[u] = E; e[++E] = edge(v, u); next[E] = first[v]; first[v] = E; } void dfs(int x, int px = 0) { int i, y; f[x] = 1, g[x] = w; for (i = first[x]; i; i = next[i]) if ((y = e[i].v) != px) { dfs(y, x); g[x] = ((ll)g[x] * (f[y] + g[y]) + (ll)f[x] * g[y]) % mod; // f[x] . g[y] + g[x] . f[y] cont, g[x] . g[y] cut. f[x] = (ll)f[x] * (f[y] + g[y]) % mod; // f[x] . f[y] cont, f[x] . g[y] cut. } } int main() { int i, u, v; ll ans; if (C == 1) return printf("%lld\n", PowerMod(n, n - 2)), 0; for (i = 1; i < n; ++i) scanf("%d%d", &u, &v), addedge(u, v); w = n * (PowerMod(1 - C, -1) - 1ll) % mod, dfs(1); ans = PowerMod(n, -2, PowerMod(1 - C, n, g[1])); printf("%lld\n", ans + (ans >> 63 & mod)); return 0; } } namespace Poly { int l, n; vec rev, x, y; void NTT_init(int len) { if (l == len) return; n = 1 << (l = len); ll g = PowerMod(root, 1 << (23 - l)); *x = 1, *rev = 0; for (int i = 1; i < n; ++i) x[i] = x[i - 1] * g % mod, rev[i] = rev[i >> 1] >> 1 | (i & 1) << (l - 1); } void DNTT(int *d, int *t) { int i, *j, *k, len = 1, delta = n, R; for (i = 0; i < n; ++i) t[rev[i]] = d[i]; for (i = 0; i < l; ++i) { delta >>= 1; for (k = x, j = y; j < y + len; k += delta, ++j) *j = *k; for (j = t; j < t + n; j += len << 1) for (k = j; k < j + len; ++k) { R = (ll)y[k - j] * k[len] % mod; k[len] = (*k - R < 0 ? *k - R + mod : *k - R); *k = (*k + R >= mod ? *k + R - mod : *k + R); } len <<= 1; } } vec B1, B2, B3, B4, B5, B6, B7; void Mul(int deg, pvec a, pvec b, pvec c) { if (!deg) {*c = (ll)*a * *b % mod; return;} NTT_init(lg2(deg) + 1); int i; ll iv = PowerMod(n, mod - 2); DNTT(a, c); DNTT(b, B1); for (i = 0; i < n; ++i) B1[i] = (ll)B1[i] * c[i] % mod; DNTT(B1, c); std::reverse(c + 1, c + n); for (i = 0; i < n; ++i) c[i] = c[i] * iv % mod; } void Inv(int deg, pvec a, pvec b) { int len, i; ll iv = half_mod; *b = PowerMod(*a, mod - 2); b[1] = 0; *B1 = *a; B1[1] = a[1]; for (len = 0; 1 << len < deg; ++len) { NTT_init(len + 2); for (i = n >> 1; i < n; ++i) b[i] = B1[i] = 0; DNTT(b, B2); DNTT(B1, B3); for (i = 0; i < n; ++i) reduce(B2[i] = B2[i] * (2ll - (ll)B2[i] * B3[i] % mod) % mod); DNTT(B2, B3); std::reverse(B3 + 1, B3 + n); half(iv); for (i = 0; i < n >> 1; ++i) b[i] = B3[i] * iv % mod; for (; i < n; ++i) b[i] = 0, B1[i] = a[i]; } } void Diff(int deg, vec a, vec b) {for (int i = 1; i <= deg; ++i) b[i - 1] = (ll)a[i] * i % mod;} void Intg(int deg, vec a, vec b, int ct = 0) {for (int i = 1; i <= deg; ++i) b[i] = (ll)a[i - 1] * inv[i] % mod, *b = ct;} void Ln(int deg, vec a, vec b) { if (!--deg) {*b = 0; return;} int i, j = deg * 2 - 1; NTT_init(lg2(j) + 1); Diff(deg, a, B4), Inv(deg, a, B5); for (i = deg; i < n; ++i) B4[i] = B5[i] = 0; Mul(j, B4, B5, B6); Intg(deg, B6, b); } void Exp(int deg, vec a, vec b) { int len, i, n = 2; *b = 1; b[1] = 0; for (len = 0; 1 << len < deg; ++len, n <<= 1) { Ln(n, b, B7); *B7 = 1; for (i = 1; i < n; ++i) reduce(B7[i] = a[i] - B7[i]); for (; i < n << 1; ++i) B7[i] = b[i] = 0; Mul((n << 1) - 1, b, B7, B6); for (i = 0; i < n; ++i) b[i] = B6[i]; for (; i < n << 1; ++i) b[i] = 0; } } } namespace Subtask3 { vec f, g; int main() { int i; ll w, ans; if (C == 1) return printf("%lld\n", PowerMod(n, 2 * (n - 2))), 0; init(n), w = (ll)n * n % mod * (PowerMod(1 - C, -1) - 1) % mod; for (i = 1; i <= n; ++i) reduce(f[i] = PowerMod(i, i, finv[i] * w % mod)); Poly::Exp(n + 1, f, g); ans = PowerMod(n, -4, PowerMod(1 - C, n, (ll)g[n] * fact[n] % mod)); printf("%lld\n", ans + (ans >> 63 & mod)); return 0; } } int main() { int op; scanf("%d%d%d", &n, &C, &op); return op ? (op == 1 ? Subtask2::main() : Subtask3::main()) : Subtask1::main(); }
- 1
信息
- ID
- 3651
- 时间
- 4000ms
- 内存
- 512MiB
- 难度
- 10
- 标签
- 递交数
- 2
- 已通过
- 1
- 上传者