zoukankan      html  css  js  c++  java
  • 【CodeForces】932 E. Team Work

    【题目】E. Team Work

    【题意】给定n和k,n个人中选择一个大小为x非空子集的代价是x^k,求所有非空子集的代价和%1e9+7。n<=10^9,k<=5000。

    【算法】斯特林反演

    【题解】枚举非空子集大小,则题目要求:

    $$ans=sum_{i=1}^{n}inom{n}{i}i^k$$

    对通常幂进行斯特林反演,得到:

    $$ans=sum_{i=1}^{n}inom{n}{i}sum_{j=1}^{k}egin{Bmatrix} k\ j end{Bmatrix}*i^{underline{j}}$$

    第二类斯特林数和i无关,因此提出来,从而尝试将下降幂和组合数搭配起来:

    $$ans=sum_{j=1}^{k}egin{Bmatrix} k\ j end{Bmatrix}sum_{i=1}^{n}frac{n!}{(n-i)!(i-j)!}$$

    如果(n-i)!(i-j)!是组合数的分母,那分子就是n-i+i-j=n-j,所以拆分$n!=(n-j)!*n^{underline{j}}$,得到:

    $$ans=sum_{j=1}^{k}egin{Bmatrix} k\ j end{Bmatrix}*n^{underline{j}}sum_{i=1}^{n}inom{n-j}{n-i}$$

    后面可以直接用组合数求和公式,得到:

    $$ans=sum_{j=1}^{k}egin{Bmatrix} k\ j end{Bmatrix}*n^{underline{j}}*2^{n-j}$$

    然后O(k^2)预处理第二类斯特林数,然后O(k log k)得到答案。如果模数是998244353的话,还可以NTT求第二类斯特林数。

    另外要注意快速幂的指数是负数时直接退出。

    #include<cstdio>
    int n,m,s[5010][5010],ans,x,M=1e9+7;
    int p(int x,int k){if(k<0)return 0;int s=1;while(k){if(k&1)s=1ll*s*x%M;x=1ll*x*x%M;k>>=1;}return s;}
    int main(){
        scanf("%d%d",&n,&m);s[1][1]=x=1;
        for(int i=2;i<=m;i++)for(int j=1;j<=m;j++)s[i][j]=(s[i-1][j-1]+1ll*s[i-1][j]*j)%M;
        for(int i=1;i<=m;i++)ans=(ans+1ll*s[m][i]*(x=1ll*x*(n-i+1)%M)%M*p(2,n-i))%M;
        printf("%d",ans);
    }
    View Code
  • 相关阅读:
    Hiveserver2高可用实现
    centos7 mysql数据库安装和配置
    ubuntu18.04 安装hadoop 2.7.3+hive 2.3.4
    imx6 RGB LCD
    imx6 KEY_ROW4 power output high fail
    ar1020 驱动移植 无效
    24C02 Twr
    undefined reference to `switch_dev_unregister'
    cannot open /proc/bus/usb/devices, No such file or directory
    imx6dl i2c4 support
  • 原文地址:https://www.cnblogs.com/onioncyc/p/8722946.html
Copyright © 2011-2022 走看看