2020年牛客多校第五场C题-easy(纯组合计数不要生成函数的做法)
文章目錄
- description
- solution
- code
description
有TTT組測試數(shù)據(jù)
對于兩個長度為KKK的數(shù)列{a}\{a\}{a}和{b}\{b\}{b},滿足∑i=1Kai=N,∑i=1Kbi=M\sum_{i=1}^Ka_i=N,\sum_{i=1}^Kb_i=M∑i=1K?ai?=N,∑i=1K?bi?=M
對于這兩個數(shù)列,定義權(quán)值為P=∏i=1Kmin?(ai,bi)P=\prod_{i=1}^K\min(a_i,b_i)P=∏i=1K?min(ai?,bi?)
求所有可能的數(shù)列的權(quán)值之和∑{a},{b}P\sum_{\{a\},\{b\}}P∑{a},{b}?P
答案對998244353998244353998244353取模
K≤min?(N,M)N,M≤5e5T≤100K\le \min(N,M)\quad N,M\le 5e5\quad T\le 100K≤min(N,M)N,M≤5e5T≤100
solution
雖然代碼非常短,但是要理解簡直要命
我們可以構(gòu)造一個二維數(shù)組c[2][K]c[2][K]c[2][K],要求c[0][i]=c[1][i]c[0][i]=c[1][i]c[0][i]=c[1][i],第i位不能為0
設(shè)計的初衷是讓c[0][K]c[0][K]c[0][K]為構(gòu)造{a}\{a\}{a},c[1][K]c[1][K]c[1][K]為構(gòu)造{b}\{b\}{b}服務(wù)
再構(gòu)造兩個一維數(shù)組A[K],B[K]A[K],B[K]A[K],B[K],第i位可以為0
通過構(gòu)造出來的這些數(shù)組生成最后的{a},{b}\{a\},\{b\}{a},{b}
- a[i]=c[0][i]+A[i]a[i]=c[0][i]+A[i]a[i]=c[0][i]+A[i]
- b[i]=c[1][i]+B[i]b[i]=c[1][i]+B[i]b[i]=c[1][i]+B[i]
定義∑i=1Kc[0][i]=∑i=1Kc[1][i]=S\sum_{i=1}^Kc[0][i]=\sum_{i=1}^Kc[1][i]=S∑i=1K?c[0][i]=∑i=1K?c[1][i]=S
則對于{a}\{a\}{a}序列而言,剩下的N?SN-SN?S就需要由AAA數(shù)組來彌補(bǔ);{b}\{b\}{b}同理
考慮有多少個A/BA/BA/B數(shù)組滿足其求和恰好彌補(bǔ)了空缺N?S/M?SN-S/M-SN?S/M?S
顯然這可以通過組合數(shù)算出
- A:C(N?S+K?1,K?1)A:C(N-S+K-1,K-1)A:C(N?S+K?1,K?1)
- B:C(M?S+K?1,K?1)B:C(M-S+K-1,K-1)B:C(M?S+K?1,K?1)
以AAA數(shù)組的計算方式為例,BBB同理
相當(dāng)于把剩下的N?SN-SN?S分成恰好KKK個盒子,隔板法,插入K?1K-1K?1個板子
但是AAA的條件可以為000,意味著盒子可以為空,但這是隔板法不能求得的
可以通過給每個盒子分配111的占位相當(dāng)于一個盒子,等價于將限制變成至少為111
考慮C(N?S+K?1,K?1)?C(M?S+K?1,K?1)C(N-S+K-1,K-1)*C(M-S+K-1,K-1)C(N?S+K?1,K?1)?C(M?S+K?1,K?1)
發(fā)現(xiàn)這兩個組合數(shù)相乘有非常實(shí)際的意義
這求出的恰好是將所有滿足?1≤i≤Kc[0][i]≤a[i]\forall_{1\le i\le K}\ c[0][i]\le a[i]?1≤i≤K??c[0][i]≤a[i]的{a}\{a\}{a}和?1≤i≤Kc[0][i]≤b[i]{b}\forall_{1\le i\le K}\ c[0][i]\le b[i]\{b\}?1≤i≤K??c[0][i]≤b[i]{b}的組合都計算了恰好一次
接著我們考慮對于一組特定的ccc數(shù)組和特定的A,BA,BA,B數(shù)組(也就是一組特定的{a},{b}\{a\},\{b\}{a},{b})的貢獻(xiàn)
∏i=1Kmin?(ai,bi)\prod_{i=1}^K\min(a_i,b_i)∏i=1K?min(ai?,bi?) 這是題目定義的貢獻(xiàn)
思考一下,這樣一組特定的{a},{b}\{a\},\{b\}{a},{b},會被多少個ccc計算到?
-  顯然是∏i=1Kmin?(ai,bi)\prod_{i=1}^K\min(a_i,b_i)∏i=1K?min(ai?,bi?) 每一位iii都滿足c[0][i]=c[1][i]≤min?(ai,bi)c[0][i]=c[1][i]\le\min(a_i,b_i)c[0][i]=c[1][i]≤min(ai?,bi?)就行,因為ccc要求不能為000,而A,BA,BA,B要求可以為000 將每一位c[i]c[i]c[i]的可取值個數(shù)相乘,即是能利用A,BA,BA,B修補(bǔ)成{a},{b}\{a\},\{b\}{a},{b}的所有ccc的組合 
于是乎,發(fā)現(xiàn)非常巧妙地將答案的乘積和轉(zhuǎn)化成了計數(shù)個數(shù)貢獻(xiàn)
再轉(zhuǎn)個彎,我們直接計算每個特定的ccc會對多少個{a},{b}\{a\},\{b\}{a},{b}提供111的計數(shù)貢獻(xiàn),求和就等價于原問題的總貢獻(xiàn)
然而,又發(fā)現(xiàn)了一個非常巧妙的性質(zhì),和(S)相同的ccc產(chǎn)生的計數(shù)貢獻(xiàn)是一樣的(但不是貢獻(xiàn)的{a},{b}\{a\},\{b\}{a},{b}完全相同的意思)
-  要證明這個性質(zhì),就需要再轉(zhuǎn)個彎,用到最開始的組合數(shù)推導(dǎo) 剩下的N?S,M?SN-S,M-SN?S,M?S都需要A,BA,BA,B的補(bǔ)給 A,BA,BA,B怎么補(bǔ)給,最后生成的{a},{b}\{a\},\{b\}{a},{b}會因此而固定 是一對一的關(guān)系 
這個計數(shù)貢獻(xiàn)自然是CS?1,K?1C_{S-1,K-1}CS?1,K?1?
-  插板法 ccc的和為SSS,要求分成KKK個盒子,盒子不能為空 相當(dāng)于有S?1S-1S?1個空位需要插入K?1K-1K?1個板 
最后就成功不用生成函數(shù)解決這道題了!!!
現(xiàn)在總結(jié),就只有一句話,最開始的c,A,Bc,A,Bc,A,B構(gòu)造簡直就是神來之筆
后面所有的推導(dǎo)全都是建立在最開始的規(guī)則設(shè)定基礎(chǔ)上
真的妙極了!!
code
#include <cstdio> #include <iostream> using namespace std; #define int long long #define mod 998244353 #define maxn 1000005 int fac[maxn], inv[maxn];int qkpow( int x, int y ) {int ans = 1;while( y ) {if( y & 1 ) ans = ans * x % mod;x = x * x % mod;y >>= 1;}return ans; }void init( int n ) {fac[0] = inv[0] = 1;for( int i = 1;i <= n;i ++ )fac[i] = fac[i - 1] * i % mod;inv[n] = qkpow( fac[n], mod - 2 );for( int i = n - 1;i;i -- )inv[i] = inv[i + 1] * ( i + 1 ) % mod; }int C( int n, int m ) {return fac[n] * inv[m] % mod * inv[n - m] % mod; }signed main() {init( 1e6 );int n, m, k, T;scanf( "%lld", &T );while( T -- ) {scanf( "%lld %lld %lld", &n, &m, &k );int ans = 0;for( int i = k;i <= min( n, m );i ++ )ans = ( ans + C( i - 1, k - 1 ) * C( n - i + k - 1, k - 1 ) % mod * C( m - i + k - 1, k - 1 ) ) % mod;printf( "%lld\n", ans );}return 0; }總結(jié)
以上是生活随笔為你收集整理的2020年牛客多校第五场C题-easy(纯组合计数不要生成函数的做法)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 下载 沙耶之歌Android_沙耶之歌安
- 下一篇: 专题突破之反悔贪心——建筑抢修,Cow
