• 洛谷P2791 幼儿园篮球题


    题目描述

    题解

    可以列出式子$$frac{sum_{i=0}^k(_i^m)(_{k-i}^{n-m})i^L}{(_k^n)}$$
    我们只关心上面那部分,套路把 $i^L$ 换掉,得$$sum_{i=0}^k(_i^m)(_{k-i}^{n-m})sum_{j=0}^L{_j^L}(_j^i)j!$$
    把 $j$ 提前,得$$sum_{j=0}^L{_j^L}j!sum_{i=0}^k(_i^m)(_{k-i}^{n-m})(_j^i)$$
    由于 $(_i^m)(_j^i)=(_j^m)(_{i-j}^{m-j})$ ,于是我们接着化$$sum_{j=0}^L{_j^L}j!(_j^m)sum_{i=0}^k(_{i-j}^{m-j})(_{k-i}^{n-m})$$
    我们观察到后面的式子,考虑其意义,就是在 $m-j$ 个中选 $i-j$ 个数乘上在 $n-m$ 个数中选出 $k-i$ 个数的总方案数,由于 $i$ 是从 $0$ 到 $k$ ,所以可以看成是在 $n-j$ 个数中选出 $k-j$ 个数,于是我们得到式子$$sum_{j=0}^L{_j^L}j!(_j^m)(_{k-j}^{n-j})$$
    于是我们可以预处理 ${_j^L}$ 即可

    代码

    #include <bits/stdc++.h>
    using namespace std;
    const int N=8e5+5,M=2e7+5,P=998244353;
    int n,m,T,L,G[2]={3,(P+1)/3},A[N],B[N],jc[M],ny[M],t=1,p,r[N];
    int X(int x){return x>=P?x-P:x;}
    int K(int x,int y){
        int z=1;
        for (;y;y>>=1,x=1ll*x*x%P)
            if (y&1) z=1ll*z*x%P;
        return z;
    }
    void Ntt(int *g,bool o){
        for (int i=0;i<t;i++)
            if (i<r[i]) swap(g[i],g[r[i]]);
        for (int wn,i=1;i<t;i<<=1){
            wn=K(G[o],(P-1)/(i<<1));
            for (int x,y,j=0;j<t;j+=(i<<1))
                for (int w=1,k=0;k<i;k++,w=1ll*w*wn%P)
                    x=g[j+k],y=1ll*w*g[i+j+k]%P,
                    g[j+k]=X(x+y),g[i+j+k]=X(x-y+P);
        }
        if (o)
            for (int i=0,v=K(t,P-2);i<t;i++)
                g[i]=1ll*v*g[i]%P;
    };
    int main(){
        cin>>n>>m>>T>>L;
        n=max(n,L);jc[0]=1;
        for (int i=1;i<=n;i++)
            jc[i]=1ll*i*jc[i-1]%P;
        ny[n]=K(jc[n],P-2);
        for (int i=n;i;i--)
            ny[i-1]=1ll*i*ny[i]%P;
        for (int i=0,F=1;i<=L;i++,F=P-F)
            A[i]=1ll*F*ny[i]%P,
            B[i]=1ll*K(i,L)*ny[i]%P;
        for (;t<L+L+2;t<<=1,p++);
        for (int i=0;i<t;i++)
            r[i]=(r[i>>1]>>1)|((i&1)<<(p-1));
        Ntt(A,0);Ntt(B,0);
        for (int i=0;i<t;i++)
            A[i]=1ll*A[i]*B[i]%P;
        Ntt(A,1);
        for (int x,k,v;T--;){
            scanf("%d%d%d",&n,&m,&k);
            v=min(min(n,m),min(k,L));x=0;
            for (int i=0;i<=v;i++)
                x=X(x+1ll*A[i]*ny[m-i]%P*jc[n-i]%P*ny[k-i]%P);
            x=1ll*x*jc[m]%P*ny[n]%P*jc[k]%P;
            printf("%d
    ",x);
        }
        return 0;
    }
  • 相关阅读:
    PAIP.MYSQL数据库比较
    paip.验证码识别----判断汉字还是英文
    SQLServer2008客户端软件
    paip.多个TOMCAT共存在一台主机上配置方法
    paip.银行卡号的发卡行归属地查询
    paip.获取当前实际北京时间API
    PAIP.HIBERNATE ORA02289 sequence does not exist的解决
    C51与汇编语言混合编程之一
    KEIL C51高级编程之二
    可重入函数与不可重入函数(转)
  • 原文地址:https://www.cnblogs.com/xjqxjq/p/12260974.html
Copyright © 2020-2023  润新知