20210524 刷题赛 乐队_题解【另一种思路】

20210524 刷题赛 乐队_题解【另一种思路】

题解给的做法是第二类斯特林数通常幂转下降幂,其实更简单的也可以直接转成牛顿级数。

F ( x ) F(x) F(x) 写成牛顿级数
F ( x ) = ∑ j = 0 k c j ( x j ) F(x)=\sum_{j=0}^k c_j {x\choose j} F(x)=j=0kcj(jx)
目标式子为
∑ i = 0 n ( n i ) 2 n − i F ( i ) = ∑ i = 0 n ∑ j = 0 k ( n i ) 2 n − i c j ( i j ) = ∑ j = 0 k ( n j ) c j ∑ i = 0 n 2 n − i ( n − j i − j ) = ∑ j = 0 k ( n j ) c j 3 n − j \begin{aligned} &\sum_{i=0}^n {n\choose i}2^{n-i}F(i)\\ =&\sum_{i=0}^n \sum_{j=0}^k {n\choose i}2^{n-i}c_j {i\choose j}\\ =&\sum_{j=0}^k {n\choose j}c_j\sum_{i=0}^n 2^{n-i}{n-j\choose i-j}\\ =&\sum_{j=0}^k {n\choose j}c_j3^{n-j} \end{aligned} ===i=0n(in)2niF(i)i=0nj=0k(in)2nicj(ji)j=0k(jn)cji=0n2ni(ijnj)j=0k(jn)cj3nj
由于我太菜了,在最后一步想了好久,最后发现可以强行给 ∑ i ( a i ) 2 i \sum_i{a\choose i} 2^i i(ia)2i 一个组合意义:

现有 a a a 个白球,你选了 i i i 个出来,并给这个 i i i 个球任意涂上红色或蓝色,问有几种涂色方案。这个就等价于现有 a a a 个球,可以给每个球任意涂上白红蓝三种颜色的一种,问方案数。

所以就有了 ∑ i ( a i ) 2 i = 3 a \sum_i{a\choose i} 2^i=3^a i(ia)2i=3a ,这个可以扩展到 ∑ i ( a i ) X i = ( X + 1 ) a \sum_i{a\choose i} X^i=(X+1)^a i(ia)Xi=(X+1)a

#include <bits/stdc++.h>
#define K 5003 
using namespace std;
typedef long long ll;
const int mod=998244853;
ll n,k,fac[K],inv[K];
ll a[K],A[K][K];
ll ksm(ll x,ll y){
    ll res=1;
    while(y){
        if(y&1) res=res*x%mod; 
        x=x*x%mod; y>>=1;
    }
    return res;
}
void init(){
    fac[0]=1;
    for(int i=1;i<=k;i++) fac[i]=fac[i-1]*i%mod;
    inv[k]=ksm(fac[k],mod-2);
    for(int i=k-1;i>=0;i--) 
        inv[i]=inv[i+1]*(i+1)%mod;
}
ll get_A(ll x){
    ll res=0,X=1;
    for(int i=0;i<=k;i++,X=X*x%mod) res=(res+X*a[i]%mod)%mod;
    return res;
}
ll C[K];
int main(){
//    freopen("band2.in","r",stdin);
    cin>>n>>k;
    init();
    for(int i=0;i<=k;i++) cin>>a[i],a[i]%=mod;
    for(int i=0;i<=k;i++) A[0][i]=get_A(i);
    for(int i=k,op=1;i>=1;i--,op++)
        for(int j=0;j<=i-1;j++)
            A[op][j]=(A[op-1][j+1]-A[op-1][j]+mod)%mod;
    for(int i=0;i<=k;i++) a[i]=A[i][0];
    C[0]=1;
    for(int i=1;i<=k;i++) C[i]=C[i-1]*(n-i+1)%mod;
    ll res=0;
    for(int i=0;i<=k;i++) 
		(res+=a[i]*C[i]%mod*inv[i]%mod*ksm(3,n-i)%mod)%=mod;
	cout<<res;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值