CF题面

题意:求\(\sum_{i=0}^{n}\binom{n}{i}i^k\)

\(n\le10^9,k\le5000\)

模\(10^9+7\)

BZOJ题面

题意:求\(n*2^{\frac{n(n-1))}{2}-(n-1)}*\sum_{i=0}^{n-1}\binom{n-1}{i}i^k\)

\(n\le10^9,k\le2*10^5\)

模\(998244353\)

第二类斯特林数

赶紧去学第二类斯特林数啊

第二类斯特林数:\(S(n,m)\),表示把\(n\)个不同的的球放到\(m\)个相同的盒子且不允许空盒的方案数。

首先有一个\(O(n^2)\)的递推。考虑第\(n\)个球的放置,如果单独放置方案数就等于\(S(n-1,m-1)\),否则就是\(m*S(n-1,m)\),表示枚举放在那个盒子里。写出来就是

\[S(n,m)=S(n-1,m-1)+m*S(n-1,m)
\]

边界条件:\(S(0,0)=1,S(i,0)=0(i>0)\)

然后还有各种考虑组和意义得出来的柿子

第二类斯特林数存在通项公式。因为\(m^n\)表示把\(n\)个不同的球放到\(m\)个不同的盒子里且允许空盒的方案数,我们想办法用这个东西构造出第二类斯特林数的组和意义。

首先盒子是否相同很好办,直接乘/除以\(m!\)即可。关键问题在于空盒的处理。

考虑容斥,计算“至少有\(k\)个空盒然后剩下的随便是不是空盒的方案数”,乘上一个容斥系数

\[S(n,m)=\frac{1}{m!}\sum_{k=0}^{m}(-1)^k\binom{m}{k}(m-k)^n
\]

还有一个,反过来用第二类斯特林数来表示\(m^n\)

其实就是一个反演,但如果也同样考虑组和意义的话岂不妙哉。

枚举有几个盒子不是空的,可以直接得到如下柿子:

\[m^n=\sum_{i=0}^{m}S(n,i)*\binom{m}{i}*i!
\]

sol

所以说这道题怎么做呢?

开始推柿子辣~

\[\sum_{i=0}^{n}\binom{n}{i}i^k=\sum_{i=0}^{n}\binom{n}{i}\sum_{j=0}^{i}S(k,j)*\binom{i}{j}*j!\\=\sum_{j=0}^{n}S(k,j)*j!\sum_{i=j}^{n}\binom{n}{i}\binom{i}{j}\\=\sum_{j=0}^{n}S
(k,j)*j!*\binom{n}{j}*2^{n-j}\\=\sum_{j=0}^{k}S
(k,j)*j!*\binom{n}{j}*2^{n-j}\]

注意\(\sum_{i=j}^{n}\binom{n}{i}\binom{i}{j}\)的组合意义:从\(n\)个里面选出任意多个(大于等于\(j\))再从中选出\(j\)个,相当于从\(n\)个中选\(j\)个然后剩下的\(n-j\)个随便选。

柿子里面的阶乘\(j!\)、组合数\(\binom{n}{j}\)、2的次幂\(2^{n-j}\)都可以\(O(k)\)处理出来。复杂度瓶颈在于第二类斯特林数的处理。

\(k\le5000\)可以直接用递推式\(O(k^2)\)处理出来,而观察其通项式会发现其实就是一个卷积形式:

\[S(n,m)=\frac{1}{m!}\sum_{k=0}^{m}(-1)^k\binom{m}{k}(m-k)^n\\=\sum_{k=0}^{m}\frac{(-1)^k}{k!}*\frac{(m-k)^n}{(m-k)!}
\]

所以直接上\(NTT\),复杂度\(O(k\log{k})\)

但是\(CF\)上的那道题不能用\(NTT\)诶,毕竟\(10^9+7\)怎么\(NTT\)(我没说不可以啊,只是我还不会呀。。。)

update 3.28 放心\(MTT\)这个坑已经填了。

code

[CF932E]Team Work

这里我强行用通项公式然后写了个\(O(k^2)\)的多项式乘法

#include<cstdio>
#include<algorithm>
using namespace std;
const int mod = 1e9+7;
int gi()
{
int x=0,w=1;char ch=getchar();
while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
if (ch=='-') w=0,ch=getchar();
while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return w?x:-x;
}
int fastpow(int a,int b)
{
int res=1;
while (b) {if (b&1) res=1ll*res*a%mod;a=1ll*a*a%mod;b>>=1;}
return res;
}
const int N = 5005;
int jc[N],C[N],two[N],inv,a[N],b[N],s[N],ans;
int main()
{
int n=gi(),k=gi();
jc[0]=1;
for (int i=1;i<=k;++i) jc[i]=1ll*jc[i-1]*i%mod;
C[0]=1;
for (int i=1;i<=k;++i) C[i]=1ll*C[i-1]*(n-i+1)%mod*fastpow(i,mod-2)%mod;
two[0]=fastpow(2,n);inv=fastpow(2,mod-2);
for (int i=1;i<=k;++i) two[i]=1ll*two[i-1]*inv%mod;
for (int i=0;i<=k;++i) a[i]=i&1?mod-fastpow(jc[i],mod-2):fastpow(jc[i],mod-2);
for (int i=0;i<=k;++i) b[i]=1ll*fastpow(i,k)*fastpow(jc[i],mod-2)%mod;
for (int i=0;i<=k;++i)
for (int j=0;j<=i;++j)
(s[i]+=1ll*a[j]*b[i-j]%mod)%=mod;
for (int i=1;i<=k;++i) (ans+=1ll*s[i]*jc[i]%mod*C[i]%mod*two[i]%mod)%=mod;
printf("%d\n",ans);
return 0;
}

[BZOJ5093]图的价值

#include<cstdio>
#include<algorithm>
using namespace std;
const int _ = 800005;
const int mod = 998244353;
int gi()
{
int x=0,w=1;char ch=getchar();
while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
if (ch=='-') w=0,ch=getchar();
while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return w?x:-x;
}
int fastpow(int a,int b)
{
int res=1;
while (b) {if (b&1) res=1ll*res*a%mod;a=1ll*a*a%mod;b>>=1;}
return res;
}
int n,N,k,l;
int jc[_],C[_],two[_],inv,a[_],b[_],rev[_],ans;
void NTT(int *P,int opt)
{
for (int i=0;i<N;++i) if (i>rev[i]) swap(P[i],P[rev[i]]);
for (int i=1;i<N;i<<=1)
{
int W=fastpow(3,(mod-1)/(i<<1));
if (opt==-1) W=fastpow(W,mod-2);
for (int j=0,p=i<<1;j<N;j+=p)
{
int w=1;
for (int k=0;k<i;++k,w=1ll*w*W%mod)
{
int x=P[j+k],y=1ll*P[j+k+i]*w%mod;
P[j+k]=(x+y)%mod;P[j+k+i]=(x-y+mod)%mod;
}
}
}
if (opt==-1)
{
int Inv=fastpow(N,mod-2);
for (int i=0;i<N;++i) P[i]=1ll*P[i]*Inv%mod;
}
}
int main()
{
n=gi()-1;k=gi();
jc[0]=1;
for (int i=1;i<=k;++i) jc[i]=1ll*jc[i-1]*i%mod;
C[0]=1;
for (int i=1;i<=k;++i) C[i]=1ll*C[i-1]*(n-i+1)%mod*fastpow(i,mod-2)%mod;
two[0]=fastpow(2,n);inv=fastpow(2,mod-2);
for (int i=1;i<=k;++i) two[i]=1ll*two[i-1]*inv%mod;
for (int i=0;i<=k;++i) a[i]=i&1?mod-fastpow(jc[i],mod-2):fastpow(jc[i],mod-2);
for (int i=0;i<=k;++i) b[i]=1ll*fastpow(i,k)*fastpow(jc[i],mod-2)%mod;
for (N=1;N<=k*2;N<<=1) ++l;--l;
for (int i=0;i<N;++i) rev[i]=(rev[i>>1]>>1)|((i&1)<<l);
NTT(a,1);NTT(b,1);
for (int i=0;i<N;++i) a[i]=1ll*a[i]*b[i]%mod;
NTT(a,-1);
for (int i=0;i<=k;++i) (ans+=1ll*a[i]*jc[i]%mod*C[i]%mod*two[i]%mod)%=mod;
int Pow=(1ll*n*(n+1)/2-n)%(mod-1);
printf("%d\n",1ll*ans*fastpow(2,Pow)%mod*(n+1)%mod);
return 0;
}

最新文章

  1. Mac 搭建 SVN 服务器环境
  2. R语言学习笔记-变量的作用域
  3. linux 新增挂载新硬盘
  4. 依赖注入及AOP简述(十)——Web开发中常用Scope简介 .
  5. 挺苹果的声音,iPhone 5s的两处进步
  6. Linux - 简明Shell编程02 - 变量(Variable)
  7. WEB项目挂载到IIS session过期
  8. 2019-4-21 - plan
  9. Vue 可输入可下拉组件的封装
  10. Python面向对象2:类与对象的成员分析及self
  11. [laravel]malformed header from script &#39;index.php&#39;: Bad header: HTTP/1.1 302 Found, referer: http://localhost/auth/login
  12. 数据处理项目Postmortem
  13. 百度地图插件(百度地图AK申请配置指南)
  14. yum安装失败:ublic key for **.rpm is not installed
  15. ns-3 的下载、编译以及 Eclipse 的相关配置
  16. java 事件通告写法
  17. 安装wordcloud第三方库Unable to find vcvarsall.bat
  18. 【ARC077F】SS
  19. 【Android】Activity 生命周期具体解释
  20. 4.1 - FTP文件上传下载

热门文章

  1. java使用*导包的性能
  2. 深入分析Java ClassLoader的原理(转)
  3. go 开发环境安装教程 windows
  4. 对于文件File类型中的目录分隔符
  5. network programming-简单的TCP客户服务器编程
  6. qt pro 设置编译参数,支持 xp
  7. PAT1119. Pre- and Post-order Traversals
  8. python+selenium+autoit实现文件上传
  9. 使用基于Android网络通信的OkHttp库实现Get和Post方式简单操作服务器JSON格式数据
  10. scrapy安装的问题