zoukankan      html  css  js  c++  java
  • Codeforces932E. Team Work

    求$sum_{i=0}^nC_n^ii^k$。n<=1e9,k<=5000。

    方法一:大力推公式

    $sum_{i=0}^nC_n^ii^k$

    闪一句:幂转斯二林(第二类斯特林数)为什么叫斯二林呢因为第一类叫斯大林!

    $=sum_{i=0}^nC_n^isum_{j=0}^{k}S(k,j)A_i^j$

    $=sum_{i=0}^nfrac{n!}{i!(n-i)!}sum_{j=0}^kS(k,j)frac{i!}{(i-j)!}$

    $=n!sum_{i=0}^nsum_{j=0}^kS(k,j)frac{1}{(n-i)!(i-j)!}$

    闪一句:重要!移花接木法,见到下面有个$(n-i)!(i-j)!$,上面立即配个$(n-j)!$,才能把j分离出来

    $=n!sum_{i=0}^nsum_{j=0}^kS(k,j)C_{n-j}^{n-i}frac{1}{(n-j)!}$

    $=n!sum_{j=0}^k S(k,j)frac{1}{(n-j)!}sum_{i=0}^nC_{n-j}^{n-i}$

    $=sum_{j=0}^k S(k,j)frac{n!}{(n-j)!}2^{n-j}$

    搞定。这样的话可以出K=1e5来考斯特林预处理。这里只写暴力。

     1 //#include<iostream>
     2 #include<cstring>
     3 #include<cstdlib>
     4 #include<cstdio>
     5 //#include<map>
     6 #include<math.h>
     7 //#include<time.h>
     8 //#include<complex>
     9 #include<algorithm>
    10 using namespace std;
    11 
    12 int n,K;
    13 #define maxn 5011
    14 const int mod=1e9+7;
    15 int dmi[maxn],two[maxn],str[maxn][maxn];
    16 int powmod(int a,int b)
    17 {
    18     int ans=1;
    19     while (b)
    20     {
    21         if (b&1) ans=1ll*ans*a%mod;
    22         a=1ll*a*a%mod; b>>=1;
    23     }
    24     return ans;
    25 }
    26 void pre(int n,int m)
    27 {
    28     str[0][0]=1;
    29     for (int i=1;i<=n;i++)
    30     {
    31         str[i][0]=0;
    32         for (int j=1;j<=i;j++) str[i][j]=(str[i-1][j-1]+1ll*j*str[i-1][j])%mod;
    33     }
    34     dmi[0]=1; for (int i=1;i<=n;i++) dmi[i]=dmi[i-1]*1ll*(m-i+1)%mod;
    35     two[0]=powmod(2,m); for (int i=1,tmp=(mod+1)>>1;i<=n;i++) two[i]=two[i-1]*1ll*tmp%mod;
    36 }
    37 int main()
    38 {
    39     scanf("%d%d",&n,&K);
    40     pre(K,n);
    41     int ans=0;
    42     for (int i=1;i<=K;i++) ans=(ans+str[K][i]*1ll*dmi[i]%mod*two[i])%mod;
    43     printf("%d
    ",ans);
    44     return 0;
    45 }
    View Code

    方法二:组合意义转换

    问题即求:对每个集合,从中可重复地挑K个人,问方案。

    那咋不能先挑人再统计集合啊?挑人之后,一个满足这挑人方案的集合有多少种呢?首先挑的这些人肯定是要有的,其他人随意。但注意,这里挑人是重复的,所以挑的人数不等于挑的人种,就是把n看成n种人。那假设挑了k个人,j种人,对答案的贡献是$2^{n-j}$。那挑i个人,j种人,有多少种方案?大力dp,$f(i,j)=f(i-1,j)*j+f(i-1,j-1)*(n-j+1)$。

    代码?自己写。

  • 相关阅读:
    20155303 实验五 网络编程与安全
    20155303 2016-2017-2 《Java程序设计》课程总结
    20155303 实验四 Android程序设计
    《Java 程序设计》课堂实践项目 课后学习总结
    20155303 实验三 敏捷开发与XP实践
    20155303 2016-2017-2 《Java程序设计》第十周学习总结
    Java第七次作业--图形用户界面
    Java第六次作业--异常处理和Java类集
    Java第五次作业--面向对象高级特性(抽象类和接口)
    Java第四次作业--面向对象高级特性(继承和多态)
  • 原文地址:https://www.cnblogs.com/Blue233333/p/8487091.html
Copyright © 2011-2022 走看看