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. JQuery如何获取按键的unicode编码?

    $("selector").keyup(function(xxx){ var myEvent = xxx; var code = myEvent.keyCode; alert(co ...

  2. 简述什么是ajax、javascript、json、Jquery?

    什么是Javascript? 基于对象.解释型.事件驱动.脚本语言.封装在<script>标签中使用.弱类型.与浏览器交互执行 什么 是Ajax? ajax是一种编程模式.在客户端与服务器 ...

  3. Maven中央仓库地址(实用版)

    最近做项目的时候,一直发现常用的oschina maven源一直都没有反应,后面发现原来oschina竟然关闭了maven源服务,后面经同事推荐了阿里云的maven源,这速度杠杠的 Maven 中央仓 ...

  4. 中面试中你不可回避的C、C++的问题(一)

    基础中的基础 局部变量与全局变量问题 (使用’ ::’) 2.      如何在另个文件中引用一个全局变量 (extern) 3.      全局变量可以定义被多个C文件包含,并且是static 4. ...

  5. Android:实现两个Activity相互切换而都不走onCreate()

    本文要实现的目的是: 有3个Activity: A,B,C.从A中能够进入B,B中能够进入C.而且B和C之间可能须要多次相互切换,因此不能使用普通的startActivity-finish方式,由于又 ...

  6. testVC.modalPresentationStyle = UIModalPresentationFormSheet; 更改 VC大小

    本文转载至 http://www.cocoachina.com/bbs/simple/?t31199.html TestViewController *testVC = [[TestViewContr ...

  7. EasyNVR无插件IPC摄像机直播方案前端构建之:区分页面是自跳转还是分享依据

    区分分享还是跳转 对于前端一些页面的展示,通常有两种方式:通过入口链接一步步进入,或是通过分享链接直接进入:对于这两种方式的区别是什么?在进行前端书写时又应该如何处理? 以EasyNVR为例来进行说明 ...

  8. JavaScript中实现继承

    今天即兴研究了下JS,查阅了相关资料 ,发现Js中没有"子类"和"父类"的概念,也没有"类"(class)和"实例"(i ...

  9. 使用服务端的临时密钥,不依赖阿里js的putFIle--》阿里oss

    <!DOCTYPE html> <html lang='en'> <head> <meta charset='UTF-8'> <title> ...

  10. Swift 学习笔记 (解决Swift闭包中循环引用的三种方法)

    话不多说 直接上代码 class SmartAirConditioner { var temperature:Int = //类引用了函数 var temperatureChange:((Int)-& ...