1 条题解

  • 0
    @ 2026-1-16 22:06:11

    #include <bits/stdc++.h>
    #define lg2 std::__lg
    using std::cin;
    using std::cout;
    
    typedef long long ll;
    const int N = 530000, mod = 998244353, iv2 = (mod + 1) / 2, root = 31;
    typedef int vec[N], *pvec;
    
    vec inv, fact, finv;
    
    inline int max(const int x, const int y) {return x < y ? y : x;}
    inline void sub(int &x, const int y) {x -= y, x += x >> 31 & mod;}
    inline int & reduce(int &x) {return x += x >> 31 & mod;}
    inline int & neg(int &x) {return x = (!x - 1) & (mod - x);}
    ll PowerMod(ll a, int n, ll c = 1) {for (; n; n >>= 1, a = a * a % mod) if (n & 1) c = c * a % mod; return c;}
    
    void init() {
    	int i;
    	for (inv[1] = 1, i = 2; i < N; ++i) inv[i] = ll(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;
    }
    
    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 = mod - (mod - 1) / n;
    		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 Diff(int deg, pvec a, pvec b) {for (int i = 1; i <= deg; ++i) b[i - 1] = (ll)a[i] * i % mod;}
    
    	void Exp(int deg, pvec a, pvec b) {
    		int i, len; ll iv = iv2; pvec c = B7; assert(!*a);
    		if (*b = 1, deg <= 1) return;
    		if (b[1] = a[1], deg == 2) return;
    
    		memset(b + 2, 0, i = 8 << lg2(deg - 1)), memset(c, 0, i), memset(B1, 0, i),
    		*c = 1, neg(c[1] = b[1]);
    
    		for (len = 1; 1 << len < deg; ++len) {
    			NTT_init(len + 1), iv = (iv >> 1) + iv2;
    
    			DNTT(c, B2), DNTT(b, B3);
    			for (i = 0; i < n; ++i) B4[i] = (ll)B3[i] * B2[i] % mod; DNTT(B4, B5);
    			for (i = n >> 1; i < n; ++i) B5[i] = B5[n - i] * iv % mod;
    
    			memset(B5, 0, n << 1), DNTT(B5, B4);
    			for (i = 0; i < n; ++i) B4[i] = (ll)B4[i] * B2[i] % mod; DNTT(B4, B5);
    			for (i = n >> 1; i < n; ++i) B5[i] = B5[n - i] * (mod - iv) % mod;
    
    			memcpy(B5, c, n << 1), DNTT(B5, B6);
    			Diff(n >> 1, b, B1), DNTT(B1, B4);
    			for (i = 0; i < n; ++i) B4[i] = (ll)B4[i] * B6[i] % mod; DNTT(B4, B6);
    			for (i = n >> 1; i < n; ++i) reduce(B5[i] = (a[i] - B6[n - i + 1] * iv % mod * inv[i]) % mod);
    
    			memset(B5, 0, n << 1), DNTT(B5, B4);
    			for (i = 0; i < n; ++i) B4[i] = (ll)B4[i] * B3[i] % mod; DNTT(B4, B5);
    			for (i = n >> 1; i < n; ++i) b[i] = B5[n - i] * iv % mod;
    
    			if (2 << len >= deg) return;
    
    			DNTT(b, B3);
    			for (i = 0; i < n; ++i) B3[i] = (ll)B3[i] * B2[i] % mod; DNTT(B3, B4);
    			for (i = n >> 1; i < n; ++i) B4[i] = B4[n - i] * iv % mod;
    
    			memset(B4, 0, n << 1), DNTT(B4, B3);
    			for (i = 0; i < n; ++i) B3[i] = (ll)B3[i] * B2[i] % mod; DNTT(B3, B4);
    			for (i = n >> 1; i < n; ++i) c[i] = B4[n - i] * (mod - iv) % mod;
    		}
    	}
    }
    
    namespace maker {
    	int n, lim, a[9];
    	vec c, f, F, E[5], EI;
    	vec C1, C2, C3, C4, C5;
    
    	void solve(int L, int w) {
    		int i, $, R = L + (1 << w), M; ll iv;
    		if (!w) {
    			if (L) {
    				int d, c = (ll(E[1][L] - E[0][L] + mod) * inv[L] + EI[L] + ll(L == *a - 1) * finv[*a]) % mod;
    				for ($ = 2; $ < n; ++$)
    					if (d = L - *a + $[a] + 1, d >= 0) c = (c + (ll)$[E][d] * finv[*a - $[a]]) % mod;
    				f[L] = c % mod, F[L] = (ll)L * f[L] % mod;
    				for ($ = 0; $ < n; ++$) $[E][L] = ((ll)$[E][L] * inv[L] + (ll)$[a] * f[L]) % mod;
    				sub(EI[L], E[0][L]);
    			} else for ($ = 0; $ < n; ++$) $[E][0] = 1;
    			return;
    		}
    		solve(L, w - 1);
    		if ((M = (1 << (w - 1)) + L) > lim) return;
    		Poly::NTT_init(w), iv = mod - (mod - 1) / Poly::n;
    		if (L) {
    			memcpy(C2, F, 4 << w), memcpy(C3, F + L, 2 << w), memset(C3 + (1 << (w - 1)), 0, 2 << w), Poly::DNTT(C2, C1), Poly::DNTT(C3, C2);
    			for ($ = 0; $ < n; ++$) {
    				memcpy(C4, $[E], 4 << w), memcpy(C5, $[E] + L, 2 << w), memset(C5 + (1 << (w - 1)), 0, 2 << w), Poly::DNTT(C4, C3), Poly::DNTT(C5, C4);
    				for (i = 0; i < Poly::n; ++i) C3[i] = ((ll)C1[i] * C4[i] + (ll)C2[i] * C3[i]) % mod;
    				Poly::DNTT(C3, C5);
    				for (i = M; i < R; ++i) $[E][i] = ($[E][i] + C5[Poly::n - (i - L)] * iv % mod * $[a]) % mod;
    				if (!$) {
    					Poly::DNTT(c, C3);
    					for (i = 0; i < Poly::n; ++i) C3[i] = (ll)C3[i] * C4[i] % mod;
    					Poly::DNTT(C3, C4);
    					for (i = M; i < R; ++i) EI[i] = (EI[i] + C4[Poly::n - (i - L)] * iv) % mod;
    				}
    			}
    		} else {
    			memcpy(C2, F, 2 << w), memset(C2 + M, 0, 2 << w), Poly::DNTT(C2, C1);
    			for ($ = 0; $ < n; ++$) {
    				memcpy(C3, $[E], 2 << w), memset(C3 + M, 0, 2 << w), Poly::DNTT(C3, C2);
    				for (i = 0; i < Poly::n; ++i) C3[i] = (ll)C1[i] * C2[i] % mod;
    				Poly::DNTT(C3, C4);
    				for (i = M; i < R; ++i) $[E][i] = ($[E][i] + C4[Poly::n - i] * iv % mod * $[a]) % mod;
    				if (!$) {
    					Poly::DNTT(c, C3);
    					for (i = 0; i < Poly::n; ++i) C2[i] = (ll)C2[i] * C3[i] % mod;
    					Poly::DNTT(C2, C3);
    					for (i = M; i < R; ++i) EI[i] = (EI[i] + C3[Poly::n - i] * iv) % mod;
    				}
    			}
    		}
    		solve(M, w - 1);
    	}
    
    	int main(int _n, int *_a, int _lim, pvec result) {
    		int i; n = _n, *a = _a[n - 1], lim = _lim;
    		for (i = 1; i < n; ++i) a[i] = *a - _a[i - 1];
    		for (i = 0; i < lim; ++i) c[i] = mod - finv[i + 1];
    		memset(f, 0, 1 << (lg2(lim) + 3)), memset(F, 0, lim << 2), memset(EI, 0, lim << 2);
    		for (i = 0; i < 5; ++i) memset(E[i], 0, lim << 2);
    		solve(0, 19);
    		for (i = 0; i < lim; ++i) f[i] = (ll)f[i] * lim % mod;
    		Poly::Exp(lim, f, F);
    		for (i = 1; i <= lim; ++i) result[i] = (ll)F[lim - i] * finv[i - 1] % mod * fact[lim - 1] % mod;
    		return 0;
    	}
    }
    
    int R, C, n, q, nr, nc;
    int ri[9], ci[9];
    vec rf, cf, f, qa, qb;
    
    int main() {
    	int i, qi, ans = 0; init();
    	std::ios::sync_with_stdio(false), cin.tie(NULL);
    	cin >> R >> C >> q >> nr >> nc, qi = PowerMod(q, mod - 2);
    	for (i = 0; i < nr; ++i) cin >> ri[i];
    	for (i = 0; i < nc; ++i) cin >> ci[i];
    	maker::main(nr, ri, R, rf), maker::main(nc, ci, C, cf);
    	n = R + C, qa[1] = *qa = 1;
    	for (i = 2; i <= n; ++i) qa[i] = (ll)qa[i - 1] * q % mod;
    	for (i = 2; i <= n; ++i) qa[i] = (ll)qa[i] * qa[i - 1] % mod;
    	n = max(R, C), qb[1] = *qb = 1;
    	for (i = 2; i <= n; ++i) qb[i] = (ll)qb[i - 1] * qi % mod;
    	for (i = 2; i <= n; ++i) qb[i] = (ll)qb[i] * qb[i - 1] % mod;
    	for (i = 1; i <= R; ++i) rf[i - 1] = (ll)rf[i] * qb[i] % mod;
    	for (i = 1; i <= C; ++i) cf[i - 1] = (ll)cf[i] * qb[i] % mod;
    	rf[R] = cf[C] = 0;
    	Poly::Mul(R + C - 2, rf, cf, f);
    	for (i = 2; i <= R + C; ++i) ans = (ans + (ll)f[i - 2] * qa[i]) % mod;
    	cout << ans << '\n';
    	return 0;
    }
    
    • 1

    信息

    ID
    2235
    时间
    5000ms
    内存
    512MiB
    难度
    10
    标签
    递交数
    4
    已通过
    4
    上传者