「ABC231 G」 Balls in Boxes 題解
阿新 • • 發佈:2022-04-11
「ABC231 G」 Balls in Boxes 題解
\(~~~~\) 終於有一道題讓我有動力起魔怔標題了。
題意
\(~~~~\) \(n\) 個盒子,初始第 \(i\) 個盒子有 \(a_i\) 個球,將 \(k\) 個球依次獨立隨機放入 \(n\) 個盒子內。定義最終狀態的權值為所有盒子內球數量的積,求期望權值。
\(~~~~\) \(1\leq n\leq 1000,1\leq k\leq 10^9\)。
題解
\(~~~~\) 期望很假,由於放球共有 \(n^k\) 種情況這很好求,所以問題在於 \(n^k\) 種情況的權值和。
\(~~~~\) 假設所有 \(a_i=0\) 怎麼做,記 \(x_{i,j}\in\{0,1\}\)
\(~~~~\) 展開的話就會是若干形似這樣的項之和:
\[\large \prod_{i=1}^n x_{i,t_i}~~~~(t_i\in [1,n]) \]\(~~~~\) 顯然當所有 \(x\) 都取 \(1\) 時其才會產生貢獻,更進一步這裡取到的 \(t_i\) 應該互不相同。那合法的 \(\{t_i\}\) 就應該
\(~~~~\) 那考慮對於已經合法的 \(\{t_i\}\) ,其他球就可以亂放了,所以每組 \(\{t_i\}\)
\(~~~~\) 所以最後的答案就是 \(\dfrac{k!}{(k-n)!}\times n^{k-n}\) ,然後除上總方案數就是期望。
\(~~~~\) 現在加上初始值,那我們認為每個盒子的增量為 \(b_i\) ,依然很好求總方案,那要求的最後的總權值期望是:
\[\large \sum_{\{b_i\}} (\prod_{i=1}^n(a_i+b_i)) \]\(~~~~\) 把裡面拆開可以發現總是由 \(x\) 項 \(a\) 的積和 \(n-x\) 項 \(b\) 的積做乘法,然後加和。
\(~~~~\)
\(~~~~\) 那最後的答案由 \(f\) 和 \(g\) 卷一下就可以得到:
\[\large \sum_{i=0}^n f_i\times g_{n-i} \]\(~~~~\) 然後再除以方案數就是期望了。
程式碼
檢視程式碼
#include <cstdio>
#include <algorithm>
#define ll long long
using namespace std;
const int MOD=998244353;
int n,k;
int arr[1005],dp[1005][1005],f[1005],g[1005];
ll qpow(ll a,ll b)
{
ll ret=1;
while(b)
{
if(b&1) ret=ret*a%MOD;
b>>=1;a=a*a%MOD;
}
return ret;
}
int Get(int x)
{
int ret=1;
for(int i=k;i>=k-x+1;i--) ret=1ll*ret*i%MOD;
return ret;
}
int main() {
scanf("%d %d",&n,&k);
dp[0][0]=1;
for(int i=1;i<=n;i++)
{
scanf("%d",&arr[i]);
for(int j=0;j<=n;j++)
dp[i][j]=(dp[i-1][j]+(j>=1?1ll*dp[i-1][j-1]*arr[i]%MOD:0))%MOD;
if(i==n) for(int j=0;j<=n;j++) f[j]=dp[i][j];
}
int Up=min(n,k);
for(int i=0;i<=Up;i++)
g[i]=1ll*Get(i)*qpow(n,k-i)%MOD;
int Ans=0;
for(int i=0;i<=n;i++) Ans=(1ll*Ans+1ll*f[i]*g[n-i]%MOD)%MOD;
printf("%lld",1ll*Ans*qpow(qpow(n,k),MOD-2)%MOD);
return 0;
}