(mathcal{Description})
Link.(完全一致)
给定 (n,m,k),对于两个长度为 (k) 的满足 (left(sum_{i=0}^ka_i=n ight)landleft(sum_{i=1}^kb_i=m ight)) 的正整数序列对 ({a_k},{b_k}),其权值为 (prod_{i=1}^kmin{a_i,b_i})。求所有序列对的权值之和,对 (998244353) 取模。
(n,m,kle10^6)。
(mathcal{Solution})
我们尝试寻找 ([x^ay^b]G(x,y)=min{a,b}~(a,b>0)) 中的 ( ext{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
ight)left(sum_{i=1}^{+infty}y^i
ight)left(sum_{i=0}^{+infty}x^iy^i
ight)
]
答案即为:
[[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
", ans );
}
return 0;
}
(mathcal{Details})
直接丢构造富有数学的美感。