【bzoj5093】[Lydsy1711月赛]图的价值(NTT+第二类斯特林数)
题意:
给定\(n\)个点,一个图的价值定义为所有点的度数的\(k\)次方之和。
现在计算所有\(n\)个点的简单无向图的价值之和。
思路:
将式子列出来:
\]
表示分别考虑每个点的贡献,我们只需要枚举其度数即可,其余的边任意连。
然后我们将后面的\(j^k\)用第二类斯特林数展开:
&\sum_{i=1}^{n}\sum_{j=0}^{n-1}{n-1\choose j}2^{\frac{(n-1)(n-2)}{2}}\sum_{t=1}^{j}{j\choose t}t!\begin{Bmatrix}
k \\ t
\end{Bmatrix}\\
=&\sum_{i=1}^n2^{\frac{(n-1)(n-2)}{2}}\sum_{t=1}^{n-1}t!\begin{Bmatrix}
k \\ t
\end{Bmatrix}\sum_{j=t}^{n-1}{n - 1 \choose j}{j \choose t}\\
=&\sum_{i=1}^n2^{\frac{(n-1)(n-2)}{2}}\sum_{t=1}^{n-1}t!\begin{Bmatrix}
k \\ t
\end{Bmatrix}\sum_{j=t}^{n-1}{n - 1 \choose j}{j \choose t}\\
=&\sum_{i=1}^n2^{\frac{(n-1)(n-2)}{2}}\sum_{t=1}^{n-1}t!{n-1\choose t}\begin{Bmatrix}
k \\ t
\end{Bmatrix}\sum_{j=t}^{n-1}{n - 1 - t\choose j - t}\\
=&\sum_{i=1}^n2^{\frac{(n-1)(n-2)}{2}}\cdot\sum_{t=1}^{n-1}2^{n-1-t}t!{n-1\choose t}\begin{Bmatrix}
k \\ t
\end{Bmatrix}\\
=&\sum_{i=1}^n2^{\frac{(n-1)(n-2)}{2}}(n-1)!\cdot\sum_{t=1}^{n-1}\frac{2^{n-1-t}}{(n-1-t)!}\begin{Bmatrix}
k \\ t
\end{Bmatrix}
\end{aligned}
\]
似乎可以不要最后一行,对于每个点预处理之后可以直接\(O(n)\)算了。
因为卷积系数要求\(\displaystyle \begin{Bmatrix}
    k \\ t
\end{Bmatrix}\),注意到这是一行的第二类斯特林数,那么我们可以直接通过\(FFT\)在\(O(klogk)\)的时间内预处理出来。预处理详见:传送门。
代码如下:
/*
 * Author:  heyuhhh
 * Created Time:  2019/12/11 22:57:14
 */
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
  #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
  void err() { std::cout << '\n'; }
  template<typename T, typename...Args>
  void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
  #define dbg(...)
#endif
void pt() {std::cout << '\n'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 2e5 + 5, MOD = 998244353;
int n, k, m;
ll qpow(ll a, ll b) {
    ll ans = 1;
    while(b) {
        if(b & 1) ans = ans * a % MOD;
        a = a * a % MOD;
        b >>= 1;
    }
    return ans;
}
const int P = 998244353, G = 3, Gi = 332748118;
int lim = 1, L, r[N * 4];
ll a[N * 4], b[N * 4];
void NTT(ll *A, int type) {
    for(int i = 0; i < lim; i++)
        if(i < r[i]) swap(A[i], A[r[i]]);
    for(int mid = 1; mid < lim; mid <<= 1) {
        ll Wn = qpow( type == 1 ? G : Gi , (P - 1) / (mid << 1)); //Wn = g ^ ((p - 1) / n)  (mod p)
        for(int j = 0; j < lim; j += (mid << 1)) {
            ll w = 1;
            for(int k = 0; k < mid; k++, w = (w * Wn) % P) {
                 int x = A[j + k], y = w * A[j + k + mid] % P;
                 A[j + k] = (x + y) % P,
                 A[j + k + mid] = (x - y + P) % P;
            }
        }
    }
}
void solve(ll *a, ll *b) {
    while(lim <= m + m) lim <<= 1, L++;
    for(int i = 0; i < lim; i++) r[i] = (r[i >> 1] >> 1) | ((i & 1) << (L - 1));
    for(int i = n + 1; i < lim; i++) a[i] = 0;  //a,b need init
    for(int i = m + 1; i < lim; i++) b[i] = 0;
    NTT(a, 1); NTT(b, 1);
    for(int i = 0; i < lim; i++) a[i] = (a[i] * b[i]) % P;
    NTT(a, -1);
    ll inv = qpow(lim, P - 2);
    for(int i = 0; i < lim; i++) a[i] = a[i] * inv % P;
}
int fac[N], inv[N], c[N];
void init() {
    fac[0] = 1;
    for(int i = 1; i < N; i++) fac[i] = 1ll * fac[i - 1] * i % MOD;
    inv[N - 1] = qpow(fac[N - 1], MOD - 2);
    for(int i = N - 2; i >= 0; i--) inv[i] = 1ll * inv[i + 1] * (i + 1) % MOD;
    c[0] = 1;
    for(int i = 1; i < N; i++) c[i] = 1ll * c[i - 1] * (n - i) % MOD * qpow(i, MOD - 2) % MOD;
    m = k;
    for(int i = 0; i <= m; i++) {
        a[i] = (i & 1) ? MOD - inv[i] : inv[i];
        b[i] = qpow(i, k) * inv[i] % MOD;
    }
    solve(a, b);
}
void run(){
    ll ans = 1ll * n * qpow(2, 1ll * (n - 1) * (n - 2) / 2) % MOD;
    ll res = 0;
    for(int i = 0; i <= m; i++) {
        res = (res + a[i] * fac[i] % MOD * c[i] % MOD * qpow(2, n - i - 1) % MOD) % MOD;
    }
    ans = ans * res % MOD;
    cout << ans << '\n';
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cout << fixed << setprecision(20);
    cin >> n >> k;
    init();
    run();
    return 0;
}
【bzoj5093】[Lydsy1711月赛]图的价值(NTT+第二类斯特林数)的更多相关文章
- BZOJ5093 [Lydsy1711月赛]图的价值  【第二类斯特林数 + NTT】
		题目链接 BZOJ5093 题解 点之间是没有区别的,所以我们可以计算出一个点的所有贡献,然后乘上\(n\) 一个点可能向剩余的\(n - 1\)个点连边,那么就有 \[ans = 2^{{n - 1 ... 
- bzoj 5093 [Lydsy1711月赛]图的价值 NTT+第二类斯特林数
		[Lydsy1711月赛]图的价值 Time Limit: 30 Sec Memory Limit: 256 MBSubmit: 245 Solved: 128[Submit][Status][D ... 
- 【BZOJ5093】图的价值(第二类斯特林数,组合数学,NTT)
		[BZOJ5093]图的价值(第二类斯特林数,组合数学,NTT) 题面 BZOJ 题解 单独考虑每一个点的贡献: 因为不知道它连了几条边,所以枚举一下 \[\sum_{i=0}^{n-1}C_{n-1 ... 
- bzoj5093:图的价值(第二类斯特林数+NTT)
		传送门 首先,题目所求为\[n\times 2^{C_{n-1}^2}\sum_{i=0}^{n-1}C_{n-1}^ii^k\] 即对于每个点\(i\),枚举它的度数,然后计算方案.因为有\(n\) ... 
- BZOJ.5093.[Lydsy1711月赛]图的价值(NTT 斯特林数)
		题目链接 对于单独一个点,我们枚举它的度数(有多少条边)来计算它的贡献:\[\sum_{i=0}^{n-1}i^kC_{n-1}^i2^{\frac{(n-2)(n-1)}{2}}\] 每个点是一样的 ... 
- 【BZOJ 4555】[Tjoi2016&Heoi2016]求和 多项式求逆/NTT+第二类斯特林数
		出处0.0用到第二类斯特林数的性质,做法好像很多,我打的是直接ntt,由第二类斯特林数的容斥公式可以推出,我们可以对于每一个i,来一次ntt求出他与所有j组成的第二类斯特林数的值,这个时候我们是O(n ... 
- bzoj 4555 [Tjoi2016&Heoi2016]求和——NTT+第二类斯特林数
		题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4555 第二类斯特林数展开式: \( S(i,j) = \frac{1}{j!} \sum\l ... 
- bzoj 4555  [Tjoi2016&Heoi2016]求和 NTT 第二类斯特林数 等比数列求和优化
		[Tjoi2016&Heoi2016]求和 Time Limit: 40 Sec Memory Limit: 128 MBSubmit: 679 Solved: 534[Submit][S ... 
- 【bzoj4555】[Tjoi2016&Heoi2016]求和(NTT+第二类斯特林数)
		传送门 题意: 求 \[ f(n)=\sum_{i=0}^n\sum_{j=0}^i\begin{Bmatrix} i \\ j \end{Bmatrix}2^jj! \] 思路: 直接将第二类斯特林 ... 
随机推荐
- windows程序设计03_读取utf8文件
			这里用到的读取utf8文件的思路特别朴素.先把utf8文件按char读取到内存里.因为utf8是变长的,为了处理方便,在内存里把char转化成wchar_t,这样一个字符就是一个wchar_t.把ut ... 
- 基于iCamera测试高清摄像头SIV100B(替代ov7670)小结
			基于iCamera测试高清摄像头SIV100B(替代ov7670)小结 先看看siv100b主要关键参数 SIV100B与OV7670分辨率和基本特性都差不多,而siv100b,像素尺寸更小,灵敏度更 ... 
- postman高级应用
			目录 提取接口返回值 设置动态参数 流程控制 调试 定义公共函数 外部数据文件 提取接口返回值 1.获取响应的header值 var Content-Type=postman.getResponseH ... 
- Electron node integration enabled 设置
			解决办法 参考博客:https://blog.csdn.net/hwytree/article/details/103167175 
- 【RabbitMQ】使用学习
			[RabbitMQ]使用学习 转载: ============================================================= =================== ... 
- python爬虫--代理.让你的ip在坚挺一会!!
			代理 代理简述 代理服务器:实现请求转发,从而可以实现更换请求的ip地址 在requests中如何将请求的ip进行更换 代理的匿名度: 透明:服务器知道你使用了代理并且知道你的真实ip 匿名:服务器知 ... 
- PAT1057 Stack(树状数组+倍增)
			目录 题目大意 题目分析 题目大意 要求维护一个栈,提供压栈.弹栈以及求栈内中位数的操作(当栈内元素\(n\)为偶数时,只是求第\(n/2\)个元素而非中间两数的平均值).最多操作100000次,压栈 ... 
- 计算密集型和 io 密集型项目的使用场景分析和代码演示
			from threading import Thread from multiprocessing import Process import time 计算密集型 def work1(): res= ... 
- java基础-对象的初始化
			一 前言 本节内容将会提到方法重载,对象的初始化,对象的构造器,和this关键字的使用,以及会简要的概括一下java中对象回收机制.觉得文章不错的读者可以关注一下作者的博客和公众号(同博客名称) 二 ... 
- SpringCloud服务降级案列
			一.什么是服务降级 所有的RPC技术里面服务降级是一个最为重要的话题,所谓的降级指的是当服务的提供方不可使用的时候,程序不会出现异常,而会出现本地的操作 二.服务降级案例 1.目录展示 2.导入依赖 ... 
