zoukankan      html  css  js  c++  java
  • 斯特林数学习笔记

    第一类斯特林数

    生成函数

    式子

    (f(x)=prodlimits_{i=0}^{n-1}(x+i))

    证明

    使用数学归纳法。

    递推式

    式子

    (left[egin{matrix}n\kend{matrix} ight]=(n-1)left[egin{matrix}n-1\kend{matrix} ight]+left[egin{matrix}n-1\k-1end{matrix} ight])

    证明

    假设最后一个元素自己成为一个圆排列,或者最后一个元素插到前面的 (n-1) 的元素的前面(后面类似),形成圆排列,也就是前面的每一个长度为 (n) 的圆排列提供了 (n) 个不同的方案来插入。

    性质

    1

    (n!=sumlimits_{i=0}^nleft[egin{matrix}n\iend{matrix} ight])

    2

    (left[egin{matrix}n\n-2end{matrix} ight]=2 imes C_n^3+3 imes C_N^4)

    求行

    倍增求解,多项式卷积,可以看洛谷的题解。

    例题

    题目1

    P5408 【模板】第一类斯特林数·行

    注意

    卡常。

    另外一定记得哪些函数需要取反,一个是

    (F(x)=LastFuntion_x imes x!)

    (LastFunction) 表示上一次倍增的函数

    一个是

    (H(x)=sumlimits_{i=0}^nF(i) imes G(n-i))

    其中

    (G(x)=frac{n^x}{x!})

    代码

    #include <cstdio>
    
    using namespace std;
    
    inline void swap (int &a, int &b) {
    	int c = a;
    	a = b,
    	b = c;
    }
    const int N = (262144 + 5) << 1, mod = 167772161, inver = 55924054;
    inline int add (int u, int v) { return u + v >= mod ? u + v - mod : u + v; }
    inline int mns (int u, int v) { return u - v < 0 ? u - v + mod : u - v; }
    inline int mul (int u, int v) { return 1LL * u * v % mod; }
    inline int qpow (int u, int v) {
    	int tot = 1, base = u % mod;
    	while (v) {
    		if (v & 1) tot = mul (tot, base);
    		base = mul (base, base);
    		v >>= 1;
    	}
    	return tot;
    }
    
    int rev[N], sz, cnt2;
    inline void NTT (int *a, int n, int bit, int flag) {
    	for (int i = 0; i < n; ++i) {
    		rev[i]  = (rev[i >> 1] >> 1) | ((i & 1) << (bit - 1));
    		if (i > rev[i]) swap (a[i], a[rev[i]]);
    	}
    	for (int l = 2; l <= n; l <<= 1) {
    		int wi = qpow (flag ? inver : 3, (mod - 1) / l),
    		m = l / 2;
    		for (int *k = a; k != a + n; k += l) {
    			int w = 1;
    			for (int i = 0; i < m; ++i) {
    				int tmp = mul (k[i + m], w);
    				k[i + m] = mns (k[i], tmp);
    				k[i] = add (k[i], tmp);
    				w = mul (w, wi);
    			}
    		}
    	}
    	int tmp = qpow (n, mod - 2);
    	for (int i = 0; i < n && flag; ++i) {
    		a[i] = mul (a[i], tmp);
    	}
    }
    
    inline void MUL (int *a, int *b, int *c, int la, int lb) {
    	static int mula[N << 1], mulb[N << 1], n, bit;
    	n = 1,
    	bit = 0;
    	while (n < la + lb - 1) n <<= 1, ++bit;
    	for (int i = 0; i < la; ++i) mula[i] = a[i]; for (int i = la; i < n; ++i) mula[i] = 0;
    	for (int i = 0; i < lb; ++i) mulb[i] = b[i]; for (int i = lb; i < n; ++i) mulb[i] = 0;
    	NTT (mula, n, bit, false), NTT (mulb, n, bit, false);
    	for (int i = 0; i < n; ++i) mula[i] = mul (mula[i], mulb[i]);
    	NTT (mula, n, bit, true);
    	for (int i = 0; i < la + lb - 1; ++i) c[i] = mula[i];
    }
    
    int fac[N], invfac[N];
    inline void init () {
    	fac[0] = 1, fac[1] = 1;
    	for (int i = 2; i <= (sz << 1); ++i) fac[i] = mul (fac[i - 1], i);
    	invfac[sz << 1] = qpow (fac[sz << 1], mod - 2);
    	for (int i = (sz << 1) - 1; i >= 0; --i) invfac[i] = mul (invfac[i + 1], i + 1);
    }
    
    inline void solve (int *a, int len) {
    	if (len == 1) { a[0] = 0, a[1] = 1; return ; }
    	static int f[N << 1], g[N << 1], h[N << 1], xd, l, r;
    	solve (a, len >> 1);
    	xd = len >> 1;
    	for (int i = 0; i <= xd; ++i) f[xd - i] = mul (a[i], fac[i]);
    	int tmp = 1;
    	for (int i = 0; i <= xd; ++i) g[i] = mul (tmp, invfac[i]), tmp = mul (tmp, xd);
    	MUL (f, g, h, xd + 1, xd + 1);
    	l = 0, r = xd; while (l < r) swap (h[l], h[r]), ++l, --r;
    	for (int i = 0; i <= xd; ++i) h[i] = mul (h[i], invfac[i]);
    	MUL (a, h, a, xd + 1, xd + 1);
    	if (len % 2) {
    		g[0] = len - 1, g[1] = 1;
    		MUL (a, g, a, len, 2);
    	}
    }
    
    int main () {
    	scanf ("%d", &sz);
    	init ();
    	static int ans[N << 1];
    	solve (ans, sz);
    	for (int i = 0; i <= sz; ++i) printf ("%d ", ans[i]);
    	return 0;
    }
    
  • 相关阅读:
    read和write函数
    Android开发(20)--RadioGroup的使用
    利用Excel批量高速发送电子邮件
    NOTIFYICONDATA结构
    辞职信模板
    使用markdown语法撰写csdn博客
    算法笔记2-优先队列(堆)(上)
    湖南两初中女生水库溺亡的最新相关信息
    《cracking the coding intreview》——链表
    java算法集训代码填空题练习1
  • 原文地址:https://www.cnblogs.com/ChiTongZ/p/11398032.html
Copyright © 2011-2022 走看看