【学术篇】CF932E Team Work && bzoj5093 图的价值
对于CF这道题, 分别考虑每种可能的集合大小, 每个大小为\(k\)的集合数量有\(\binom nk\)个, 所以最后的答案就是
\]
对于bzoj这道题, 我们分别考虑每个点的贡献, 这个点可以和其他\(n-1\)个点连任意条边, 贡献是\(\sum_{i=0}^{n-1}\binom{n-1}ii^k\)
此时其他\(n-1\)个点间的\(\frac{(n-1)(n-2)}2\)条边可连可不连, 所以有\(2^{\frac{(n-1)(n-2)}2}\)种选择, 最后再乘以点数, 我们要求的就是
\]
我们看这个\(n-1\)非常不爽, 不妨将读进来的\(n\)直接自减一下代替\(n-1\), 那我们要求的就是
\]
前面的乘法和快速幂都贼jr简单, 所以我们问题的关键也就变得和上面一样, 求
\]
然后一看这个式子直接算肯定是完全过不去的, 我们就要化式子.
我们首先就要根据第二类斯特林数的性质把\(k\)次幂转化为下降幂.
(你问什么是下降幂? 就是说\(n^\underline{k}=n(n-1)(n-2)\cdots(n-k+1)\)这样的啊~如果你愿意也可以看成\(n!/(n-k)!\))
\]
然后把组合数和下降幂都展开发现可以前后约掉一个\(i!\)
\]
然后收拾下式子, 把\(n!\)提出来, \(\sum\)提前,
\]
然后我们发现后面可以搞成一个组合数的形式, 我们考虑乘一个\((n-j)!\)化成组合数, 然后再把它除掉...
\]
我们把只和\(j\)有关的式子提到前面, 顺便把\(n!\)重新乘进去
\]
由于\(i\)从\(0\)取到\(n\), 所以组合数一定能取遍\([0,n-j]\)的每个数, 而且比\(n-j\)大的部分组合数都是0. 所以由组合数的性质可知$$\sum_{i=0}n\binom{n-j}{n-i}=2{n-j}$$
所以最终可以把原式化为
\]
众所周知, 第二类斯特林数说的是
把\(n\)个球放到\(k\)个盒子中, 要求盒子非空的方案数. (盒子和球均无标号)
所以如果前\(n-1\)个球放到了\(k-1\)个盒子中, 那么第\(n\)个球只好放到第\(k\)个集合中; 而如果前\(n-1\)个球放进了\(k\)个盒子, 那么第\(n\)个球只要放到任意一个盒子中就行了.
\]
很显然这样处理斯特林数是\(O(k^2)\)的, 对于CF上这道题来说, \(k\leq5000\), 这样做就可以跑过了. AC代码:
#include <cstdio>
const int p=1e9+7;
int s[5050][5050],cur[5050];
int qpow(int a,long long b,int s=1){
for(;b;b>>=1,a=1ll*a*a%p)
if(b&1) s=1ll*s*a%p;
return s;
}
int main(){
int n,k,ans=0; scanf("%d%d",&n,&k);
s[0][0]=cur[0]=1;
for(int i=1;i<=k;++i){
cur[i]=1ll*cur[i-1]*(n-i+1)%p;
for(int j=1;j<=k;++j){
s[i][j]=s[i-1][j-1]+1ll*s[i-1][j]*j%p;
if(s[i][j]>=p) s[i][j]-=p;
}
}
for(int i=0;i<=k&&i<=n;++i){
ans+=1ll*qpow(2,n-i,s[k][i])*cur[i]%p;
if(ans>=p) ans-=p;
} printf("%d",ans);
}
但是对于bzoj上这道题来说, \(k\leq 200000\), 再\(O(k^2)\)预处理就不行了. 我们考虑还有没有别的方法来处理斯特林数.
我们注意到实际上我们用到的斯特林数只有第\(k\)行这一行的数, 我们没有必要求出前\(k-1\)行来.
我们假设现在有\(n\)个球要放到\(m\)个盒子中, 我们可以让先给盒子标号, 最后的方案数除以\(m!\)即可.
然后我们枚举空盒子的数量\(k\), 一共有\(\binom mk\)种空盒子的选择方案, 然后\(n\)个球可以在\((m-k)\)个盒子中随便放.
然后根据容斥我们就可以得出
\]
我们把组合数拆开
\]
然后我们令\(f(x)=\frac{(-1)^x}{x!}, g(x)=\frac{x^n}{x!}\), 就可以发现
\]
是个明显的卷积形式, 而题目中又给了\(998244353\)作为模数, 自然NTT一下就可以咯~(其实这是我写的第一道卷积非模板题)代码:
#include <cstdio>
#include <algorithm>
const int N=606060,p=998244353;
int wn[20],nw[20],f[N],g[N],rev[N],n,lg;
int m,k,fac[N],cur[N],inv[N];
int qpow(int a,long long b,int s=1){
for(;b;b>>=1,a=1ll*a*a%p)
if(b&1ll) s=1ll*s*a%p;
return s;
}
void calcw(){
int x=qpow(3,p-2);
for(int i=0;i<20;++i){
wn[i]=qpow(3,(p-1)/(1<<i));
nw[i]=qpow(x,(p-1)/(1<<i));
}
}
void init(){
for(int i=0;i<n;++i)
rev[i]=(rev[i>>1]>>1)|((i&1)<<lg);
fac[0]=inv[0]=cur[0]=1;
for(int i=1;i<=k;++i) fac[i]=1ll*fac[i-1]*i%p;
for(int i=1;i<=k;++i) cur[i]=1ll*cur[i-1]*(m-i+1)%p;
inv[k]=qpow(fac[k],p-2);
for(int i=k-1;i;--i) inv[i]=1ll*inv[i+1]*(i+1)%p;
for(int i=0;i<=k;++i){
f[i]=(i&1?-inv[i]+p:inv[i])%p;
g[i]=1ll*qpow(i,k)*inv[i]%p;
}
}
void ntt(int *y,bool f){
for(int i=0;i<n;++i) if(i<rev[i]) std::swap(y[i],y[rev[i]]);
for(int m=2,id=1;m<=n;m<<=1,++id){
for(int k=0;k<n;k+=m){
int w=1,wm=f?wn[id]:nw[id];
for(int j=0;j<m>>1;++j){
int &a=y[k+j]; int &b=y[k+j+m/2];
int u=a%p,t=1ll*w*b%p;
a=u+t; if(a>=p) a-=p;
b=u-t; if(b<0) b+=p;
w=1ll*w*wm%p;
}
}
} int x=qpow(n,p-2);
if(!f) for(int i=0;i<n;++i) y[i]=1ll*y[i]*x%p;
}
int main(){
scanf("%d%d",&m,&k); --m;
for(n=1;n<=k+1;n<<=1,++lg); n<<=1;
init(); calcw(); ntt(f,1); ntt(g,1);
for(int i=0;i<n;++i) f[i]=1ll*f[i]*g[i]%p;
ntt(f,0); int ans=0;
for(int i=0;i<=k&&i<=m;++i){
ans+=1ll*qpow(2,m-i,cur[i])*f[i]%p;
if(ans>=p) ans-=p;
}
ans=1ll*ans*qpow(2,1ll*m*(m-1)/2,m+1)%p;
printf("%d",ans);
}
【学术篇】CF932E Team Work && bzoj5093 图的价值的更多相关文章
- [CF932E]Team Work & [BZOJ5093]图的价值
CF题面 题意:求\(\sum_{i=0}^{n}\binom{n}{i}i^k\) \(n\le10^9,k\le5000\) 模\(10^9+7\) BZOJ题面 题意:求\(n*2^{\frac ...
- 【题解】BZOJ5093图的价值(二项式+NTT)
[题解]BZOJ5093图的价值(二项式+NTT) 今天才做这道题,是我太弱了 强烈吐槽c++这种垃圾语言tmd数组越界不re反倒去别的数组里搞事情我只想说QAQ 推了一张A4纸的式子 考虑每个点的度 ...
- [BZOJ5093]图的价值(NTT+第二类Stirling数)
5093: [Lydsy1711月赛]图的价值 Time Limit: 30 Sec Memory Limit: 256 MBSubmit: 250 Solved: 130[Submit][Sta ...
- BZOJ5093图的价值(斯特林数)
题目描述 “简单无向图”是指无重边.无自环的无向图(不一定连通). 一个带标号的图的价值定义为每个点度数的k次方的和. 给定n和k,请计算所有n个点的带标号的简单无向图的价值之和. 因为答案很大,请对 ...
- bzoj5093图的价值:多项式,斯特林数(二项式反演)
Description “简单无向图”是指无重边.无自环的无向图(不一定连通). 一个带标号的图的价值定义为每个点度数的k次方的和. 给定n和k,请计算所有n个点的带标号的简单无向图的价值之和. 因为 ...
- Bzoj5093: 图的价值
题面 Bzoj Sol 一张无向无重边自环的图的边数最多为\(\frac{n(n-1)}{2}\) 考虑每个点的贡献 \[n*2^{\frac{n(n-1)}{2} - (n-1)}\sum_{i=0 ...
- BZOJ5093 图的价值(NTT+斯特林数)
显然每个点会提供相同的贡献.于是现在只考虑1号点的贡献.若其度数为i,则在2~n号点选i个连上,剩下的边随便连,这样可以算出答案为 这个式子可以O(n)计算.发现k比较小,于是考虑如何将这个式子化为与 ...
- bzoj5093:图的价值(第二类斯特林数+NTT)
传送门 首先,题目所求为\[n\times 2^{C_{n-1}^2}\sum_{i=0}^{n-1}C_{n-1}^ii^k\] 即对于每个点\(i\),枚举它的度数,然后计算方案.因为有\(n\) ...
- BZOJ5093 图的价值——推式子+第二类斯特林数
原题链接 题解 题目等价于求这个式子 \[ans=n2^{\frac{(n-1)(n-2)}{2}}\sum\limits_{i=0}^{n-1}\binom{n-1}{i}i^k\] 有这么一个式子 ...
随机推荐
- 从vue的组件传值着手浅谈观察者模式
首先,提到观察者模式,这不禁让我想到了MVVM,MVVM架构模式感觉用到了观察者的思想. 我们还是按照惯例,了解一下什么是观察者模式 观察者模式,类似发布订阅模式,完成这个动作首先最少得有两个不同的对 ...
- 如何打开mongo运行环境
新建一个文件夹,例如我的在E:\2016web\myapp\src\database 打开数据库 mongod --dbpath=E:/2016web/myapp/src/database 在新开一个 ...
- 力扣 —— Two Sum ( 两数之和) python实现
题目描述: 中文: 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案.但是,你不能重复利 ...
- 【虚拟机】:"该虚拟机似乎正在使用中。 如果该虚拟机未在使用,请按“获取所有权(T)”按钮获取它的所有权。否则,请按“取消(C)”按钮以防损坏。"
1.可能是由于上次使用虚拟机,没有正常关闭出现了这种情况,于是把问题复制粘贴搜了一下. 2.出现了如下可行的解决方法:把后缀名为.vmdk.lck的都删除掉. 3.然后再打开虚拟机就可以了.
- c++后台开发面试常见知识点总结(六)算法手写
链表倒转 leetcode-206 连续子数组最大和问题(和最大的连续子序列的和) leetcode-53 输出字符串中最长的回文子串长度? leetcode-5 一个字符串,求最长无重复子串 ...
- vim常用的骚操作
1.设置~/.vimrc syntax on 支持语法高亮 set nu 显示行号set nonu 不显示行号 set ai 设置自动缩进 set ...
- 关于respond.js
作用:可以让ie8及以下支持css3的媒体查询. 有几个问题: 1.由于浏览器的安全机制,Respond.js 不能在通过 file:// 协议(打开本地HTML文件所用的协议)访问的页面上发挥正常的 ...
- <Jmeter入门不放弃>之<2.常用功能>
大家这里参考学习的时候,我就不在这里配截图了,因为需要你打开工具根据文档自己去找,才有印象,大家一定要启动JMeter!跟着理解操作 一.测试计划 用来描述一个性能测试,所有内容都是基于这个计划,这谁 ...
- react教程 — 开发 总结
本文章是在熟练使用 VUE 的基础上,对比VUE 功能进行的一个技术总结. 1.react项目快速搭建 https://blog.csdn.net/mapbar_front/article/deta ...
- sequel 远程连接 MySQL 连接错误Can't connect to MySQL server on (61)
Mac sequel Pro链接时报错Can’t connect to MySQL server on ‘xx.xx.xx.xx’ (61). PS. win版Navicat 报错Can’t conn ...