• Luogu P5824 十二重计数法(小球盒子计数)


    Link

    假如有(n)个球,要放进(m)个盒子,求方案数。

    ( ext{I}):球之间互不相同,盒子之间互不相同。

    显然答案为(m^n)

    ( ext{II}):球之间互不相同,盒子之间互不相同,每个盒子至多装一个球。

    依次把球放进盒子,放第(i)个球时有(m-i+1)种方案,因此答案为(m^{underline n})

    ( ext{III}):球之间互不相同,盒子之间互不相同,每个盒子至少装一个球。

    相当于把(n)个数划分为(m)个有序集合,因此答案为(left{natop m ight}m!)

    ( ext{IV}):球之间互不相同,盒子全部相同。

    枚举有多少个盒子放了球,然后方案数就是将(n)个数划分为若干个无序集合,因此答案为(sumlimits_{i=1}^mleft{natop i ight})

    ( ext{V}):球之间互不相同,盒子全部相同,每个盒子至多装一个球。

    显然答案为([nle m])

    ( ext{VI}):球之间互不相同,盒子全部相同,每个盒子至少装一个球。

    显然答案为(left{natop m ight})

    ( ext{VII}):球全部相同,盒子之间互不相同。

    每个盒子装任意个球都只有一种方案,OGF为(frac1{1-x}),因此答案为([x^n]frac1{(1-x)^m}={n+m-1choose n})

    ( ext{VIII}):球全部相同,盒子之间互不相同,每个盒子至多装一个球。

    显然答案为({mchoose n})

    ( ext{IX}):球全部相同,盒子之间互不相同,每个盒子至少装一个球。

    此时每个盒子装球的OGF为(frac x{1-x}),因此答案为([x^n]frac{x^m}{(1-x)^m}={n-1choose m-1})

    ( ext{X}):球全部相同,盒子全部相同。

    相当于将(n)划分为(m)个无序自然数的和,答案为(p(n+m,m)=[x^n]prodlimits_{i=1}^mfrac1{1-x^i})

    ( ext{XI}):球全部相同,盒子全部相同,每个盒子至多装一个球。

    显然答案为([nle m])

    ( ext{XII}):球全部相同,盒子全部相同,每个盒子至少装一个球。

    相当于将(n)划分为(m)个无序正整数的和,答案为(p(n,m)=[x^{n-m}]prodlimits_{i=1}^mfrac1{1-x^i})

    #include<cstdio>
    #include<cstring>
    #include<numeric>
    #include<algorithm>
    const int N=524289,P=998244353;
    int n,m,deg,len,fac[N],inv[N],ifac[N],rev[N],w[N],S[N],p[N];
    int inc(int a,int b){return a+=b-P,a+=a>>31&P;}
    int dec(int a,int b){return a-=b,a+=a>>31&P;}
    int mul(int a,int b){return 1ll*a*b%P;}
    int pow(int a,int k){int r=1;for(;k;k>>=1,a=mul(a,a))if(k&1)r=mul(a,r);return r;}
    int C(int n,int m){return m<0||m>n? 0:mul(mul(fac[n],ifac[m]),ifac[n-m]);}
    int getlen(int n){return 1<<(32-__builtin_clz(n));}
    void init(int n)
    {
        int lim=1<<(len=32-__builtin_clz(n)),g=pow(3,(P-1)/lim);
        w[lim>>1]=1,fac[0]=ifac[0]=inv[0]=fac[1]=ifac[1]=inv[1]=1;
        for(int i=1;i<lim;++i) rev[i]=(rev[i>>1]>>1)|(i&1? lim>>1:0);
        for(int i=(lim>>1)+1;i<lim;++i) w[i]=mul(w[i-1],g);
        for(int i=(lim>>1)-1;i;--i) w[i]=w[i<<1];
        for(int i=2;i<=lim;++i) fac[i]=mul(fac[i-1],i),ifac[i]=mul(ifac[i-1],inv[i]=mul(inv[P%i],P-P/i));
    }
    void NTT(int*a,int lim,int f)
    {
        if(!~f) std::reverse(a+1,a+lim);
        for(int i=0,x=len-__builtin_ctz(lim);i<lim;++i) if(i<rev[i]>>x) std::swap(a[i],a[rev[i]>>x]);
        for(int i=1;i<lim;i<<=1) for(int j=0,d=i<<1;j<lim;j+=d) for(int k=0,x;k<i;++k) x=mul(a[i+j+k],w[i+k]),a[i+j+k]=dec(a[j+k],x),a[j+k]=inc(a[j+k],x);
        if(!~f) for(int i=0,x=P-(P-1)/lim;i<lim;++i) a[i]=mul(a[i],x);
    }
    void Inv(int*a,int*b,int deg)
    {
        if(deg==1) return b[0]=pow(a[0],P-2),void();
        static int t[N];int lim=getlen(deg*2-2);
        Inv(a,b,(deg+1)>>1),memcpy(t,a,deg<<2),memset(t+deg,0,(lim-deg)<<2);
        NTT(t,lim,1),NTT(b,lim,1);
        for(int i=0;i<lim;++i) b[i]=mul(dec(2,mul(b[i],t[i])),b[i]);
        NTT(b,lim,-1),memset(b+deg,0,(lim-deg)<<2);
    }
    void Der(int*a,int*b,int deg){for(int i=1;i<deg;++i)b[i-1]=mul(a[i],i);b[deg-1]=0;}
    void Int(int*a,int*b,int deg){for(int i=1;i<deg;++i)b[i]=mul(a[i-1],inv[i]);b[0]=0;}
    void Ln(int*a,int*b,int deg)
    {
        static int t[N];int lim=getlen(deg*2-2);
        Inv(a,t,deg),Der(a,b,deg),NTT(t,lim,1),NTT(b,lim,1);
        for(int i=0;i<lim;++i) t[i]=mul(t[i],b[i]);
        NTT(t,lim,-1),Int(t,b,deg),memset(t,0,lim<<2),memset(b+deg,0,(lim-deg)<<2);
    }
    void Exp(int*a,int*b,int deg)
    {
        if(deg==1) return b[0]=1,void();
        static int t[N];int lim=getlen(deg*2-2);
        Exp(a,b,(deg+1)>>1),Ln(b,t,deg);
        for(int i=0;i<deg;++i) t[i]=dec(a[i],t[i]);
        memset(t+deg,0,(lim-deg)<<2),++t[0],NTT(t,lim,1),NTT(b,lim,1);
        for(int i=0;i<lim;++i) b[i]=mul(b[i],t[i]);
        NTT(b,lim,-1),memset(b+deg,0,(lim-deg)<<2),memset(t+deg,0,(lim-deg)<<2);
    }
    void calcS()
    {
        static int F[N],G[N],lim=1<<len,deg=std::min(n,m)+1;
        for(int i=0;i<deg;++i) F[i]=mul(pow(i,n),ifac[i]),G[i]=i&1? P-ifac[i]:ifac[i];
        NTT(F,lim,1),NTT(G,lim,1);
        for(int i=0;i<lim;++i) S[i]=mul(F[i],G[i]);
        NTT(S,lim,-1),memset(S+deg,0,(lim-deg)*4);
    }
    void calcp()
    {
        static int F[N];
        for(int i=1;i<=m;++i) for(int j=i;j<=n;j+=i) F[j]=inc(F[j],inv[j/i]);
        Exp(F,p,n+1);
    }
    int main()
    {
        scanf("%d%d
    ",&n,&m);
        init(2*std::max(n,m)),calcS(),calcp();
        printf("%d
    ",pow(m,n));
        printf("%d
    ",mul(C(m,n),fac[n]));
        printf("%d
    ",mul(S[m],fac[m]));
        printf("%d
    ",std::accumulate(S+1,S+m+1,0,inc));
        printf("%d
    ",n<=m);
        printf("%d
    ",S[m]);
        printf("%d
    ",C(m+n-1,n));
        printf("%d
    ",C(m,n));
        printf("%d
    ",C(n-1,m-1));
        printf("%d
    ",p[n]);
        printf("%d
    ",n<=m);
        printf("%d
    ",n<m? 0:p[n-m]);
    }
    
  • 相关阅读:
    DPDK安装方法 17.12.13
    numa.h:No such file or directory 解决方法
    17秋 软件工程 第六次作业 Beta冲刺 Scrum3
    17秋 软件工程 第六次作业 Beta冲刺 总结博客
    17秋 软件工程 第六次作业 Beta冲刺 Scrum2
    Paper Reviews and Presentations
    17秋 软件工程 第六次作业 Beta冲刺 Scrum1
    17秋 软件工程 第六次作业 Beta冲刺
    error: could not create '/System/Library/Frameworks/Python.framework/Versions/2.7/share': Operation not permitted
    17秋 软件工程 个人作业 软件产品案例分析
  • 原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/12659575.html
Copyright © 2020-2023  润新知