ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【LGP5162】WD与积木

2019-03-19 19:51:24  阅读:244  来源: 互联网

标签:WD frac 积木 int sum times LGP5162 re 我们


题目

场面过度玄学,容易引起不适

我们发现我们要求的这个期望由分母和分子两部分构成

易发现

\[Ans=\frac{\sum_{i=1}^nS_2(n,i)\times i\times i!}{\sum_{i=1}^nS_2(n,i)\times i!}\]

结合\(NTT\)求斯特林数卷积我们就能过掉\(subtask2\)

考虑正解,我们显然不能再用斯特林数搞了

于是考虑一下\(dp\)

设\(f_n\)表示分母,即\(f_n=\sum_{i=1}^nS_2(n,i)\times i!\)

我们发现

\[f_i=\sum_{j=1}^{i}f_{i-j}\binom{i}{j}\]

我们强行规定\(f_0=1\)

这个柿子我们可以这样理解,先从\(i\)个数里选取\(j\)个数作为第一组,之后剩下的\(i-j\)在后面自由形成若干组

这非常正确,因为对于任何一种情况,其每一分组都有机会被选中成为第一组,而剩下的组会任意排列,于是正确性显然

我们考虑拆开组合数

\[ f_i=\sum_{j=1}^if_{i-j}\frac{i!}{j!(i-j)!} \]

\[ \frac{f_i}{i!}=\sum_{j=1}^i\frac{f_{i-j}}{(i-j)!}\times \frac{1}{j!} \]

设\(f'_i=\frac{f_i}{i!},g_i=\frac{1}{i!}\)

写成生成函数,别忘了我们强行规定\(f_0=1\)

\[ F'=\sum_{i=0}(\sum_{j=1}^if'_{i-j}g_j+[i=0])x^i \]

\[ F'=1+F'G \]

于是\(F'=(1-G)^{-1}\)

但是发现好像不太得劲,因为 \(1-G\)的最低项为\(0\),我们没法求逆

但是我们注意到\(g_0\)全程都没有出现,于是我们又强行规定\(g_0=0\)

于是我们现在可以愉快的求逆了

同理我们也可以表示出分母上的柿子

\[ h_i=\sum_{j=1}^i\binom{i}{j}h_{i-j}+\binom{i}{j}f_{i-j}=f_i+\sum_{j=1}^i\binom{i}{j}h_{i-j} \]

这里不需要强行\(h_0=1\)了

我们还是按照刚才的套路得到

\[H'=\frac{1}{(1-G)^2}\]

但是并不知道为什么这里答案算出来总会多\(1\)

肯定是我太菜了生成函数求错了

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define re register
#define LL long long
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
const int maxn=262144+1005;
inline int read() {
    char c=getchar();int x=0;while(c<'0'||c>'9') c=getchar();
    while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
}
int n,ask[100005],len,rev[maxn],T;
const LL mod=998244353;
const LL G[2]={3,332748118};
LL fac[maxn],ifac[maxn];
LL D[maxn],C[maxn],K[maxn],a[maxn],b[maxn],c[maxn],t[maxn];
inline LL ksm(LL a,LL b) {LL S=1;while(b) {if(b&1) S=S*a%mod;b>>=1;a=a*a%mod;}return S;}
inline void NTT(LL *f,int o) {
    for(re int i=0;i<len;i++) if(i<rev[i]) std::swap(f[i],f[rev[i]]);
    for(re int i=2;i<=len;i<<=1) {
        int ln=i>>1;LL og1=ksm(G[o],(mod-1)/i);
        for(re int l=0;l<len;l+=i) {
            LL t,og=1;
            for(re int x=l;x<l+ln;x++) {
                t=(og*f[ln+x])%mod;
                f[ln+x]=(f[x]-t+mod)%mod;
                f[x]=(f[x]+t)%mod;
                og=(og*og1)%mod;
            }
        }
    }
    if(!o) return;
    LL inv=ksm(len,mod-2);
    for(re int i=0;i<len;i++) f[i]=(f[i]*inv)%mod;
}
inline void mul(int n,LL *A,LL *B) {
    len=1;while(len<n+n) len<<=1;
    for(re int i=0;i<len;i++) rev[i]=rev[i>>1]>>1|((i&1)?len>>1:0);
    NTT(A,0),NTT(B,0);for(re int i=0;i<len;i++) A[i]=(A[i]*B[i])%mod;
    NTT(A,1);for(re int i=n;i<len;i++) A[i]=0;
}
inline void Inv(int n,LL *A,LL *B) {
    if(n==1) {B[0]=ksm(A[0],mod-2);return;}
    Inv((n+1)>>1,A,B);
    memset(C,0,sizeof(C));memset(K,0,sizeof(K)),memset(D,0,sizeof(D));
    for(re int i=0;i<n;i++) C[i]=A[i],D[i]=K[i]=B[i];
    mul(n,K,C);mul(n,K,D);
    for(re int i=0;i<n;i++) B[i]=(2ll*B[i]-K[i]+mod)%mod;
}
int main() {
    T=read();
    for(re int i=1;i<=T;i++) 
        ask[i]=read(),n=max(n,ask[i]+1);
    fac[0]=1;
        for(re LL i=1;i<n;i++) fac[i]=(fac[i-1]*i)%mod;
    ifac[n-1]=ksm(fac[n-1],mod-2);
    for(re LL i=n-2;i>=0;--i) ifac[i]=(ifac[i+1]*(i+1))%mod;
    for(re int i=0;i<n;i++) 
        b[i]=mod-ifac[i],b[i]%=mod;
    b[0]=1;b[0]%=mod;
    Inv(n,b,a);
    for(re int i=0;i<n;i++) t[i]=c[i]=a[i];
    mul(n,t,c);
    for(re int i=1;i<=T;i++) {
        LL q=t[ask[i]],p=a[ask[i]];
        printf("%lld\n",q*ksm(p,mod-2)%mod-1);
    }
    return 0;
}

标签:WD,frac,积木,int,sum,times,LGP5162,re,我们
来源: https://www.cnblogs.com/asuldb/p/10560802.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有