【Atcoder】 [ABC231G] Balls in Boxes

题目链接

AT方向
Luogu方向

题目解法

首先求期望变成计数
然后考虑生成函数,因为是有顺序的,所以用 e g f egf egf
考虑列出式子: a n s = k ! n k [ x k ] ∑ i = 1 n ∑ j = 0 ∞ ( a i + j ) x j j ! ans=\frac{k!}{n^k}[x^k]\sum\limits_{i=1}^n\sum\limits_{j=0}^{\infty}(a_i+j)\frac{x^j}{j!} ans=nkk![xk]i=1nj=0(ai+j)j!xj
化简,因为 a i a_i ai 是定值, j j j 可以和后面的 1 j ! \frac{1}{j!} j!1 相乘变成 1 ( j − 1 ) ! \frac{1}{(j-1)!} (j1)!1,所以拆开 a i + j a_i+j ai+j,可得
a n s = k ! n k [ x k ] ∑ i = 1 n ∑ j = 0 ∞ ( a i x j j ! + x j ( j − 1 ) ! ) = k ! n k [ x k ] ∑ i = 1 n ∑ j = 0 ∞ ( a i + x ) e x = k ! n k [ x k ] e n x ∑ i = 1 n ∑ j = 0 ∞ ( a i + x ) = k ! n k [ x k ] ( ∑ i = 0 ∞ n i i ! ) ( ∑ i = 1 n ∑ j = 0 ∞ ( a i + x ) ) ans=\frac{k!}{n^k}[x^k]\sum\limits_{i=1}^n\sum\limits_{j=0}^{\infty}(a_i\frac{x^j}{j!}+\frac{x^j}{(j-1)!})\\ =\frac{k!}{n^k}[x^k]\sum\limits_{i=1}^n\sum\limits_{j=0}^{\infty}(a_i+x)e^x\\ =\frac{k!}{n^k}[x^k]e^{nx}\sum\limits_{i=1}^n\sum\limits_{j=0}^{\infty}(a_i+x)\\ =\frac{k!}{n^k}[x^k](\sum\limits_{i=0}^{\infty}\frac{n^i}{i!})(\sum\limits_{i=1}^n\sum\limits_{j=0}^{\infty}(a_i+x)) ans=nkk![xk]i=1nj=0(aij!xj+(j1)!xj)=nkk![xk]i=1nj=0(ai+x)ex=nkk![xk]enxi=1nj=0(ai+x)=nkk![xk](i=0i!ni)(i=1nj=0(ai+x))
后面的 ∑ i = 1 n ∑ j = 0 ∞ ( a i + x ) \sum\limits_{i=1}^n\sum\limits_{j=0}^{\infty}(a_i+x) i=1nj=0(ai+x) 可以 d p dp dp 暴力卷,所以可以写成 a n s = k ! n k [ x k ] ( ∑ i = 0 ∞ n i i ! ) F ( x ) ans=\frac{k!}{n^k}[x^k](\sum\limits_{i=0}^{\infty}\frac{n^i}{i!})F(x) ans=nkk![xk](i=0i!ni)F(x)
因为后面的 F ( x ) F(x) F(x) 只有 n n n 项,不妨直接枚举其次数
a n s = 1 n k ∑ i = 0 n F ( x , i ) n k − i k i ‾ ans=\frac{1}{n^k}\sum\limits_{i=0}^nF(x,i)n^{k-i}k^{\underline i} ans=nk1i=0nF(x,i)nkiki
可以直接计算
时间复杂度 O ( n 2 ) O(n^2) O(n2),使用分治 n t t ntt ntt 代替 d p dp dp 可以做到 O ( n l o g 2 n ) O(nlog^2n) O(nlog2n)

#include <bits/stdc++.h>
#define F(i,x,y) for(int i=(x);i<=(y);i++)
#define DF(i,x,y) for(int i=(x);i>=(y);i--)
#define ms(x,y) memset(x,y,sizeof(x))
#define SZ(x) (int)x.size()-1
using namespace std;
typedef long long LL;
typedef unsigned long long ull;
typedef pair<int,int> pii;
template<typename T> void chkmax(T &x,T y){ x=max(x,y);}
template<typename T> void chkmin(T &x,T y){ x=min(x,y);}
const int N=1100,P=998244353;
int n,k,a[N];
inline int read(){
    int FF=0,RR=1;
    char ch=getchar();
    for(;!isdigit(ch);ch=getchar()) if(ch=='-') RR=-1;
    for(;isdigit(ch);ch=getchar()) FF=(FF<<1)+(FF<<3)+ch-48;
    return FF*RR;
}
int coef[N];
int qmi(int a,int b){
    int res=1;
    for(;b;b>>=1){
        if(b&1) res=1ll*res*a%P;
        a=1ll*a*a%P;
    }
    return res;
}
int main(){
    n=read(),k=read();
    F(i,1,n) a[i]=read();
    coef[0]=1;
    F(i,1,n) DF(j,n,0) coef[j]=(coef[j-1]+1ll*coef[j]*a[i])%P;
    int mul=1,ans=0;
    F(i,0,min(n,k)){
        ans=(ans+1ll*mul*qmi(n,k-i)%P*coef[i])%P;
        mul=1ll*mul*(k-i)%P;
    }
    ans=1ll*ans*qmi(qmi(n,k),P-2)%P;
    printf("%d\n",ans);
    fprintf(stderr,"%d ms\n",int(1e3*clock()/CLOCKS_PER_SEC));
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值