1 条题解

  • 0
    @ 2026-1-16 23:03:56

    #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
    上传者