Live2D

Solution -「LOCAL」「cov. 牛客多校 2020 第五场 C」Easy

\(\mathcal{Description}\)

  Link.(完全一致)

  给定 \(n,m,k\),对于两个长度为 \(k\) 的满足 \(\left(\sum_{i=0}^ka_i=n\right)\land\left(\sum_{i=1}^kb_i=m\right)\) 的正整数序列对 \(\{a_k\},\{b_k\}\),其权值为 \(\prod_{i=1}^k\min\{a_i,b_i\}\)。求所有序列对的权值之和,对 \(998244353\) 取模。

  \(n,m,k\le10^6\)

\(\mathcal{Solution}\)

  我们尝试寻找 \([x^ay^b]G(x,y)=\min\{a,b\}~(a,b>0)\) 中的 \(\text{OGF}\) \(G(x,y)\)。由于 \(x^ay^b=(xy)^{\min\{a,b\}}x^{a-\min\{a,b\}}y^{b-\min\{a,b\}}\),相当于要数出 \(x^ay^b\)\(xy\) 的个数。枚举 \(xy\) 的指数,就有:

\[\min\{a,b\}x^ay^b=\sum_{i=0}^{\min\{a,b\}-1}(xy)^ix^{a-i}y^{b-i} \]

  构造一下,有:

\[G(x,y)=\left(\sum_{i=1}^{+\infty}x^i\right)\left(\sum_{i=1}^{+\infty}y^i\right)\left(\sum_{i=0}^{+\infty}x^iy^i\right) \]

  答案即为:

\[[x^ny^m]G^k(x,y) \]

  枚举 \(xy\) 的指数,三项的贡献均可以用隔板法算出来,故单组 \(\mathcal O(n)\) 得解。

\(\mathcal{Code}\)

#include <cstdio>

const int MAXN = 2e6, MOD = 998244353;
int n, m, K, fac[MAXN + 5], ifac[MAXN + 5];

inline int qkpow ( int a, int b, const int p = MOD ) {
	int ret = 1;
	for ( ; b; a = 1ll * a * a % p, b >>= 1 ) ret = 1ll * ret * ( b & 1 ? a : 1 ) % p;
	return ret;
}

inline void init () {
	fac[0] = 1;
	for ( int i = 1; i <= MAXN; ++ i ) fac[i] = 1ll * i * fac[i - 1] % MOD;
	ifac[MAXN] = qkpow ( fac[MAXN], MOD - 2 );
	for ( int i = MAXN - 1; ~i; -- i ) ifac[i] = ( i + 1ll ) * ifac[i + 1]  % MOD;
}

inline int comb ( const int n, const int m ) {
	return n < m ? 0 : 1ll * fac[n] * ifac[m] % MOD * ifac[n - m] % MOD;
}

int main () {
//	freopen ( "easy.in", "r", stdin );
//	freopen ( "easy.out", "w", stdout );
	init (); int T;
	for ( scanf ( "%d", &T ); T --; ) {
		scanf ( "%d %d %d", &n, &m, &K );
		int ans = 0, up = n < m ? n : m;
		for ( int i = 0; i <= up; ++ i ) {
			ans = ( ans + 1ll * comb ( i + K - 1, K - 1 ) * comb ( n - i - 1, K - 1 ) % MOD
				* comb ( m - i - 1, K - 1 ) ) % MOD;
		}
		printf ( "%d\n", ans );
	}
	return 0;
}

\(\mathcal{Details}\)

  直接丢构造富有数学的美感。

posted @ 2020-09-04 15:45  Rainybunny  阅读(186)  评论(0编辑  收藏  举报