NTT+组合数学

$把每个点分别按度数考虑,由于有标号,可以得出$

$ans=n*2^{(n-1)*(n-2)}*\sum_{i=1}^{n-1}{C(n-1,i)*i^{k}}$

$本质上是求\sum_{i=1}^{n}{C(n,i)*i^{k}}$

$组合数永远是一个比较好化简的东西,问题在于i^{k}$

$通常有两种方式可以化简,一种利用第二类斯特林数,另一种是利用伯努利数,这里利用第二类斯特林数的组合意义$

$考虑i^{k}的组合意义,相当于把k个不同的物品放进i个不同的箱子$

$S(n,k)表示把n个不同元素拆成k个集合的方案数$

$注意这里要枚举集合数,因为箱子允许空,集合不允许空,所以转化成加法原理$

$考虑转化,枚举多少个箱子有东西,也就是拆成几个集合$

$n^{k}=\sum_{i=1}^{n}{S(k,i)*C(n,i)*i!}$

$得出\sum_{i=1}^{n}{C(n,i)*i^{k}}=\sum_{i=1}^{n}{C(n,i)\sum_{j=1}^{i}{S(k,j)*C(i,j)*j!}}$

$然而并无卵用,这个东西还是不能快速求$

$改变求和顺序\sum_{j=1}^{n}{S(k,j)*j!\sum_{i=j}^{n}{C(n,i)*C(i,j)}}$

$考虑里面组合数的意义,C(n,i)*C(i,j),表示先从n个里选了i个,再从i个里选j个,相当于先选j个,剩下的随便选不选$

$那么就是C(n,j)*2^{n-j},里面的sigma消掉了$

$所以变成\sum_{j=1}^{n}{S(k,j)*j!*C(n,j)*2^{n-j}}$

$问题就变成了如何快速求第二类斯特林数$

$由于给定了k,所以我们可以通过NTT快速预处理出斯特林数$

$考虑容斥原理,S(k,j)表示将k个不同的数划分成j个集合,那么j个集合都非空$

$用容斥原理弱化这个式子,\frac{1}{j!}\sum_{i=0}^{j}{(-1)^{i}*C(j,i)*(j-i)^{k}}$

$先保证至少,那么i个集合是空的,剩下的随便放,那么放k个数的方案就是(j-i)^{k}$

$但是这里的集合是无序的,所以我们还得除一个j!$

$化简一下得出S(k,j)=\sum_{i=0}^{j}{\frac{(-1)^{i}}{i!}*\frac{(j-i)^{k}}{(j-i)!}}$

$这很卷积,那么直接NTT预处理第二类斯特林数,然后O(n)算出答案即可$

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 4e5 + , P = ;
int n, m, k, len;
ll ans;
ll a[N << ], b[N << ], fac[N], inv[N], facinv[N], fac_n[N];
ll power(ll x, ll t) {
ll ret = ;
for(; t; t >>= , x = x * x % P) {
if(t & ) {
ret = ret * x % P;
}
}
return ret;
}
void ntt(ll *a, int f) {
for(int i = ; i < n; ++i) {
int t = ;
for(int j = ; j < len; ++j) {
if(i >> j & ) {
t |= << (len - j - );
}
}
if(i < t) {
swap(a[i], a[t]);
}
}
for(int l = ; l <= n; l <<= ) {
int m = l >> ;
ll w = power(, f == ? (P - ) / l : (P - ) - (P - ) / l);
for(int i = ; i < n; i += l) {
ll t = ;
for(int k = ; k < m; ++k, t = t * w % P) {
ll x = a[i + k], y = t * a[i + m + k] % P;
a[i + k] = (x + y) % P;
a[i + k + m] = ((x - y) % P + P) % P;
}
}
}
if(f == -) {
ll inv = power(n, P - );
for(int i = ; i < n; ++i) {
a[i] = a[i] * inv % P;
}
}
}
int main() {
scanf("%d%d", &m, &k);
--m;
fac[] = ;
inv[] = ;
facinv[] = ;
fac_n[] = ;
for(int i = ; i <= k; ++i) {
fac[i] = fac[i - ] * i % P;
fac_n[i] = fac_n[i - ] * (m - i + ) % P;
if(i != ) {
inv[i] = (P - P / i) * inv[P % i] % P;
}
facinv[i] = facinv[i - ] * inv[i] % P;
}
n = ;
len = ;
while(n <= k * ) {
n <<= ;
++len;
}
for(int i = ; i <= k; ++i) {
a[i] = facinv[i] * ((i & ) ? - : );
a[i] = ((a[i] % P) + P) % P;
b[i] = power(i, k) * facinv[i] % P;
}
ntt(a, );
ntt(b, );
for(int i = ; i < n; ++i) {
a[i] = a[i] * b[i] % P;
}
ntt(a, -);
for(int i = ; i <= k && i <= m; ++i) {
ans = (ans + a[i] * fac[i] % P * facinv[i] % P * fac_n[i] % P * power(, m - i) % P) % P;
}
ans = ans * (m + ) % P * power(, (ll)m * (m - ) / ) % P;
printf("%lld\n", ans);
return ;
}

bzoj5093的更多相关文章

  1. 【BZOJ5093】图的价值(第二类斯特林数,组合数学,NTT)

    [BZOJ5093]图的价值(第二类斯特林数,组合数学,NTT) 题面 BZOJ 题解 单独考虑每一个点的贡献: 因为不知道它连了几条边,所以枚举一下 \[\sum_{i=0}^{n-1}C_{n-1 ...

  2. [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 ...

  3. BZOJ5093 图的价值(NTT+斯特林数)

    显然每个点会提供相同的贡献.于是现在只考虑1号点的贡献.若其度数为i,则在2~n号点选i个连上,剩下的边随便连,这样可以算出答案为 这个式子可以O(n)计算.发现k比较小,于是考虑如何将这个式子化为与 ...

  4. BZOJ5093 [Lydsy1711月赛]图的价值 【第二类斯特林数 + NTT】

    题目链接 BZOJ5093 题解 点之间是没有区别的,所以我们可以计算出一个点的所有贡献,然后乘上\(n\) 一个点可能向剩余的\(n - 1\)个点连边,那么就有 \[ans = 2^{{n - 1 ...

  5. 【CF932E】Team Work/【BZOJ5093】图的价值 数学+NTT

    [CF932E]Team Work 题意:求$\sum\limits_{i=1}^nC_n^ii^k$,答案模$10^9+7$.$n\le 10^9,k\le 5000$. [BZOJ5093]图的价 ...

  6. [BZOJ5093]图的价值(NTT+第二类Stirling数)

    5093: [Lydsy1711月赛]图的价值 Time Limit: 30 Sec  Memory Limit: 256 MBSubmit: 250  Solved: 130[Submit][Sta ...

  7. 【题解】BZOJ5093图的价值(二项式+NTT)

    [题解]BZOJ5093图的价值(二项式+NTT) 今天才做这道题,是我太弱了 强烈吐槽c++这种垃圾语言tmd数组越界不re反倒去别的数组里搞事情我只想说QAQ 推了一张A4纸的式子 考虑每个点的度 ...

  8. Bzoj5093: 图的价值

    题面 Bzoj Sol 一张无向无重边自环的图的边数最多为\(\frac{n(n-1)}{2}\) 考虑每个点的贡献 \[n*2^{\frac{n(n-1)}{2} - (n-1)}\sum_{i=0 ...

  9. BZOJ5093图的价值(斯特林数)

    题目描述 “简单无向图”是指无重边.无自环的无向图(不一定连通). 一个带标号的图的价值定义为每个点度数的k次方的和. 给定n和k,请计算所有n个点的带标号的简单无向图的价值之和. 因为答案很大,请对 ...

  10. bzoj5093:[Lydsy1711月赛]图的价值

    题目 首先考虑到这是一张有标号的图,每一个点的地位是相等的,因此我们只需要求出一个点的价值和乘上\(n\)就好了 考虑一个点有多少种情况下度数为\(i\) 显然我们可以让除了这个点的剩下的\(n-1\ ...

随机推荐

  1. java 泛型小小的测试题

    判断以下哪种书写时正确的? 1.ArrayList<String> lists = new ArrayList<String>();2.ArrayList<Object& ...

  2. android菜鸟学习笔记9----Activity(二)

    关于Activity的生命周期: 下面是Activity整个生命周期中,状态发生变化时所回调的方法,它们对应着Activity完整的生命过程. void  onCreate(Bundle savedI ...

  3. git修改commit说明

    当发现说明写错了时,执行git commit --amend,然后修改说明即可.

  4. 镜像回源主要用于无缝迁移数据到OSS,即服务已经在自己建立的源站或者在其他云产品上运行,需要迁移到OSS上,但是又不能停止服务,此时可利用镜像回写功能实现。

    管理回源设置_管理文件_开发指南_对象存储 OSS-阿里云 https://help.aliyun.com/document_detail/31865.html 通过回源设置,对于获取数据的请求以多种 ...

  5. Greedy Function Approximation:A Gradient Boosting Machine

    https://statweb.stanford.edu/~jhf/ftp/trebst.pdf page10 90% to 95% of the observations were often de ...

  6. Swift 学习笔记(扩展和泛型)

    在开始介绍Swift中的扩展之前,我们先来回忆一下OC中的扩展. 在OC中如果我们想对一个类进行功能的扩充,我们会怎么做呢. 对于面向对象编程的话,首先会想到继承,但是继承有两个问题. 第一个问题:继 ...

  7. python 创建一个实例:步骤二 添加行为方法,编写方法

    添加方法 class Person(): def __init__(self,name,job=None,pay=0): self.name= name self.job = job self.pay ...

  8. sed 简单用法

    sed的一个简单用法: eg:在某一个文件中的一个aaa字段前后添加某些字段. 在aaa前面添加字段:sed -ne 's/aaa/&HELLO/p' test 输出结果:aaaHELLO 在 ...

  9. Pentaho BIServer Community Edtion 6.1 使用教程 第一篇 软件安装

    一.简介: Pentaho BI Server 分为企业版和社区版两个版本.其中 社区版 CE(community edtion) 为免费版本. 二.下载CE版(CentOS): 后台下载命令: no ...

  10. python之virtualenv 与 virtualenvwrapper 详解

    在使用 Python 开发的过程中,工程一多,难免会碰到不同的工程依赖不同版本的库的问题: 亦或者是在开发过程中不想让物理环境里充斥各种各样的库,引发未来的依赖灾难. 此时,我们需要对于不同的工程使用 ...