zoukankan      html  css  js  c++  java
  • 多项式入门

    入门知识点

    FFT/NTT

    这里令 (A(x)) 表示多项式 (A)(x) 处的取值,(A[x]) 表示多项式 (A) 的第 (x) 项.

    卷积形如:

    (C[r]=sum_{p,q}[(p+q)mod n=r]A[p] imes B[q])

    (w^{i})(1)(i) 次单位根.

    则有 (frac{1}{n}sum_{k=0}^{n-1}w^{vk}=[vmod n=0])

    而上面 (C[r]=sum_{p,q}[(p+q)mod n=r]A[p] imes B[q]) 中有一个特判:([(p+q)mod n=r])

    我们考虑将这个特判换掉:

    (Rightarrow) ([(p+q-r)mod n=0])

    (Rightarrow frac{1}{n}sum_{k=0}^{n-1}w^{(p+q-r)k})

    展开,得 (frac{1}{n}sum_{k=0}^{n-1}w^{-rk}w^{pk}w^{qk})

    那么,(C[r]=sum_{p,q}frac{1}{n}sum_{k=0}^{n-1}w^{-rk}w^{pk}w^{qk} A[p] imes B[q])

    整理得好看一点,可得 (C[r]=frac{1}{n}sum_{k=0}^{n-1}(w^{-r})^ksum_{p=0}^{n-1}(w^k)^pA[p]sum_{q=0}^{n-1}(w^k)^qB[q])

    (C[r]=frac{1}{n}sum_{k=0}^{n-1}(w^{-r})^k A(w^k)B(w^k))

    构造多项式 (G), 满足 (G[k]=A(w^k)B(w^k)) ,然后求出 (frac{G(w^{-r})}{n}) 就是 (C[r]) 了.

    注意:这里的这个 (n) 决定着多项式的循环节~

    FWT

    FWT是用来解决位运算卷积的.

    或卷积和与卷积还是挺好理解的,但是异或卷积就不太好理解了.

    反正只需要知道结论就行了,直接给出结论:

    或卷积:

    (FWT[A]=merge(FWT[A0],FWT[A0]+FWT[A1]))

    (UFWT[A']=merge(UFWT[A0'],UFWT[A1']-UFWT[A0']))

    (G(i)=sum_{j|i=i} g(j)),则 (G(i)H(i)=F(i))

    与卷积:

    (FWT[A]=merge(FWT[A0]+FWT[A1],FWT[A1]))

    (UFWT[A']=merge(UFWT[A0']-UFWT[A1'],UFWT[A1']))

    (F(i)=sum_{ j & i=i} f(j)),则 (G(i)H(i)=F(i))

    异或卷积:

    (FWT[A]=merge(FWT[A0]+FWT[A1],FWT[A0]-FWT[A1]))

    (UFWT[A']=merge(frac{FWT[A0']+FWT[A1']}{2},frac{FWT[A0']-FWT[A1']}{2}))

    (G(i)=sum_{j=0}^{2^n-1} (-1)^{bit(j &i)} g(j))

    单位根反演

    上面我们介绍 FFT/NTT 原理时用的其实就是单位根反演.

    ([k|n]=frac{1}{k}sum_{i=0}^{k-1}w_{k}^{ni})

    证明的话用等比数列求和公式就行(当 (n) 整除 (k) 的时候公比为 (1),每一项的贡献都是 (1),否则为 (0))


    拉格朗日插值

    我们知道,(n+1) 个不同的点可以确定以个 (n) 次多项式.

    那么,如果已知 (n+1) 个不同的点,能否由这些点确定的多项式在 (k) 处的取值呢 (?)

    拉格朗日插值就是求这个东西的.

    直接给出公式:

    (f(k)=prod_{i=0}^{n}y_{i}prod_{i eq j}frac{k-x_{j}}{x_{i}-x_{j}})

    除了这个,还有一个比较常用的:

    (1) 对于 (x) 数值连续的

    (f(k)=sum_{i=0}^{n}y_{i}prod_{i eq j}frac{k-j}{i-j})

    然后发现对于分子我们可以提前算出前缀/后缀积,然后分母的话发现就是两个阶乘相乘.

    (Rightarrow f(k)=sum_{i=0}^{n}y_{i}frac{pre_{i-1} imes suf_{i+1}}{fac[i] imes fac[n-i]})

    秦九韶算法

    如何在 (O(n)) 的时间复杂度内求出一个 (n) 次多项式的点值 (?)

    将答案从高次项往低次项带,这样可以保证只会进行 (2 imes n) 次左右的操作,常数很小.

    多项式基础操作

    多项式求逆

    这个一般指的是模意义下的求逆(一般是模多项式的最高次幂+1)

    因为如果不取模的话以个多项式的逆可能是无限长的(就像在整数中有除不尽的现象)

    结论:(Bequiv 2B'-AB'^2(mod x^n))(B')(A)(mod x^{frac{n}{2}}) 意义下的逆)

    证明:

    [A imes (B-B') equiv 0(mod x^{frac{n}{2}}) ]

    [A imes B' equiv 1(mod x^{frac{n}{2}}) ]

    [A imes (B-B') equiv 0(mod x^{frac{n}{2}}) ]

    [(B-B') equiv 0(mod x^{frac{n}{2}}) ]

    [B^2-2BB'+B'^2 equiv 0(mod x^n) ]

    [A(B^2-2BB'+B'^2)equiv 0(mod x^n) ]

    [B-2B'+AB'^2equiv 0(mod x^n) ]

    [B equiv 2B'-AB'^2(mod x^n) ]

    这个也可以求分治 FFT

    求递推式:

    (f[i]=left{egin{matrix} 1 & if & i=0\ sum_{j=1}^{i}f[i-j]g[j]& otherwise& end{matrix} ight.)

    的前 (n) 项 (答案对质数取模)

    (f[i]=sum_{j=1}^{i}f[i-j]g[j])

    (Rightarrow g[i]=f[i]-sum_{j=1}^{i-1}f[j]g[i-j]) (这个把 (f,g) 换一下,然后把 (j=0) 的部分单独拿出来就行了)

    (h[i]=left{egin{matrix} 1 & if& i=0\ -g[i] & otherwise & end{matrix} ight.)

    [g[i]=f[i]+sum_{j=1}^{i-1}f[j](-g[i-j]) ]

    [g[i]=f[i]h[0]+sum_{j=1}^{i-1}f[j]h[i-j] ]

    [g[i]=sum_{j=1}^{i}f[j]h[i-j] ]

    我们有一个小问题:(j) 的下界是 (1),而不是 (0).

    那就直接让 (f[0]=0) 就行了.

    则有 (g=f*h),求一个多项式的逆即可.

    分治FFT

    上面刚刚介绍多项式求逆如何爆踩分治 FFT qaq.....

    求: (f[i]=left{egin{matrix} 1 & if & i=0\ sum_{j=1}^{i}f[i-j]g[j]& otherwise& end{matrix} ight.)

    我们可以采用 CDQ分治的策略:先计算左面的 (f),然后用左面的 (f) 去贡献右面的 (g),再递归计算右面.

    多项式除法

    注意:这里指的是带余除法.

    证明什么的就略过了,直接给出公式好了:

    (F(x)=Q(x)G(x)+R(x))

    (F(x)_{R}) 的意思是将一个多项式的系数翻转

    这里 (n,m) 分别是 (F,Q) 的最高次幂

    (Rightarrow Q_{R}(x)=F_{R}(x)G_{R}^{-1}(x)(mod x^{n-m+1}))

    (Rightarrow R(x)=F(x)-G(x)Q(x))

    多项式开根

    给定 (n-1) 次多项式 (A(x),)(mod x^n) 意义下得多项式 (B(x),) 使得 (B^2(x)equiv A(x) (mod x^n))

    一般都会保证 (A[0]=1),否则就会非常麻烦

    直接给出公式:

    (B(x)=frac{A(x)+B'^2(x)}{2B'(x)}) ((B'(x))((mod n^{frac{n}{2}})) 意义下开出的根)

    用类似于多项式求逆得递归/倍增的求法来求即可.

    这里千万要注意:对 (B'(x)) 求逆时一定要保留 (n) 位,因为以个 (n) 次多项式的逆是无限长的.

    (B(x)=2B'^{-1}(x)[A(x)+B'(x)])

    除了 (B'(x)) 是一个 (frac{n}{2}) 次的多项式以外,其余都是 (n) 次多项式!!!

    多项式积分

    求导和积分是互逆的(你对以个函数求导,然后再积分回去是原函数),但是常数项就没了 ~

    给出公式:

    (int F(x)=sum_{i=0}^{n}frac{a_{i}}{i+1}x^{i+1})

    多项式求导

    导数是具有可加性的,所以说我们只需对每一项都求导,然后加一起即可.

    (F'(x)=sum_{i=1}^{n}ia_{i}x^{i-1})

    然后常数项就丢了 ~

    多项式取 ln

    这个的推导过程还是很有趣的.

    求:(ln(A(x)))

    求导:(ln'(A(x))=ln'(A(x))A'(x)=frac{A'(x)}{A(x)})

    再积分弄回去:(int frac{A'(x)}{A(x)}=ln(A(x)))

    然后你发现常数项就丢了,但是一般会保证 (A[0]=1),所以可以放心地使用.

    多项式 exp

    求多项式 (F(x)=e^{A(x)}(mod x^n))

    (F_{0}(x)=e^{A(x)} (mod x^frac{n}{2}))

    则有 (F(x)=F_{0}(x)(1-ln F_{0}(x)+A(x))(mod x^n))


    多项式毒瘤操作

    任意模数NTT

    为了满足单位根的性质,NTT 需要模数是质数,且能被写成 (a2^k+1) 的形式,其中 (2^k) 还要大于序列长度.

    比较常用的有 998244353,1004535809,469762049...

    如果模数任意,就不能直接用 NTT 了.

    令多项式最大系数为 (m),则该多项式系数不会大于 (nm^2)

    而如果 (mleqslant 10^9) 的话这个范围是在 (2^{24}) 以内的.

    所以我们可以用 3 个 NTT 模数分别求一次 NTT,然后用 CRT 来合并.

    这样等同于我们是对 (lcm(p1,p2,p3)) 取模,而一般来说这个 (lcm) 是大于系数的极限值的.

    那么,我们要合并的是

    [egin{Bmatrix} xequiv a_{1}& (mod m_{1})\xequiv a_{2} & (mod m_{2})\ xequiv a_{3} & (mod m_{3})end{Bmatrix} ]

    然后我们可以在 long long 范围内合并前两个,得

    [left{egin{matrix}xequiv A &(mod M) \ xequiv a_{3} & (mod m_{3})end{matrix} ight. ]

    最终答案是 (ans=KM+A)

    (K) 需要满足 (KM+Aequiv a_{3}(mod m_{3}))

    所以 (Kequiv (a_{3}-A)M^{-1}(mod m_{3}))

    求出 (K) 后就可以在原模数意义下求出 (ans=KM+A)

    这里特别强调一下如何进行第一步合并:

    由于模数互质,所以不必使用 exgcd,直接令 (x'=a_{1}m_{2} imes inv(m_{2},m_{1})+a_{2}m_{1} imes inv(m_{1},m_{2}))

    多项式多点求值

    给定 (n) 次多项式 (A(x)),求该多项式在 (left { x_{1},x_{2},...x_{m} ight }) 处的取值.

    (1...m) 建一棵线段树,每个区间维护该区间的 (x) 对应的多项式(即要维护出如果你把 (x_{l},...x_{r}) 带入这个区间的多项式能等价于带入 (A(x))

    构造 (P_{0}=prod_{i=1}^{frac{n}{2}}(x-x_{i})) 不难看出这是一个 (frac{n}{2}) 次的多项式,构造 (A_{0}(x)) 使得 (A(x)=P_{0}(x)Q(x)+A_{0}(x))

    这样的话当我们将 (x_{l},....x_{l+frac{n}{2}}) 这些值带入右边的式子会得到 (A(x)=A_{0}(x))

    (A(x)equiv A_{0}(mod P_{0}(x)))

    而根据多项式除法的性质,(A_{0}) 的次数一定小于 (P_{0}) ,即 (A_{0}) 是一个 (frac{n}{2}-1) 次幂的多项式.

    那么我们就做到了将线段树中子树规模减半的操作,对于右子树同理.

    (P) 的话可以在建立线段树的时候就预处理出来,然后边遍历这颗线段树边就行取模即可.

    时间复杂度为 (O(nlog^2n)),常数巨大无比,需要预处理单位根,并在项数小的时候秦九昭暴力展开才行.

    多项式快速插值

    给定一个 (n-1) 次多项式上的 (n) 个不同点,求这个多项式每一项的系数.

    考虑 (O(n^2)) 怎么做:直接上拉格朗日插值公式就行:(f(x)=sum_{i=1}^{n}y_{i}frac{prod_{i eq j}x-x_{j}}{prod_{i eq j}x_{i}-x_{j}})

    快速插值是基于这个式子去进行一些优化.

    (Rightarrow f(x)=sum_{i=1}^{n}frac{y_{i}}{prod_{i eq j}{x_{i}-x_{j}}}prod_{i eq j}x-x_{j})

    先考虑下面的那个 (prod_{i eq j}x_{i}-x_{j}) 怎么算:

    (g(x)=prod_{i=1}^{n}(x-x_{i}))(h(x)=(x-x_{i})),则 (prod_{i eq j}(x_{i}-x_{j})=frac{g(x_{i})}{h(x_{i})})

    然而,我们发现上面和下面都是 0 ,好像算不了.

    洛必达法则:

    如果

    [lim_{x ightarrow a} f(x)=0,lim_{x ightarrow a} g(x)=0 ]

    则有

    [lim_{x ightarrow a} frac{g(x)}{f(x)}=lim_{x ightarrow a}frac{g'(x)}{f'(x)} ]

    带入后你发现 (h'(x)=1),所以 (prod_{i eq j}(x_{i}-x_{j})=g'(x_{i}))

    我们可以把 (g(x)) 看成一个多项式,然后我们要求 (g(x_{1}),g(x_{2}),....g(x_{n})) 这个可以用多项式多点求值来做.

    预处理完 (g(x_{i})),我们考虑继续化简 (f(x))

    (f_{l,r}=sum_{i=l}^{r}frac{y_{i}}{g'(x_{i})}prod_{j=l,i eq j} (x-x_{j}))

    (Rightarrow prod_{j=mid+1}^{r}(x-x_{j})sum_{i=l}^{mid}frac{y_{i}}{g'(x_{i})}prod_{j=l(j eq i)}^{mid}(x-x_{j})+prod_{j=l}^{mid}(x-x_{j})sum_{i=mid+1}^{r}frac{y_{i}}{g'(x_{i})}prod_{j=mid+1(j eq i)}^{r}(x-x_{j}))

    然后你发现后面那一坨就是 (f_{l,mid})(f_{mid+1,r})

    (Rightarrow f_{l,mid}prod_{j=mid+1}^{r}(x-x_{j})+f_{mid+1,r}prod_{j=l}^{mid}(x-x_{j}))

    这样,我们就能自底向上推出 (f_{1,n})

    一共会被分成 (O(log n)) 层,每层 (O(n log n)) ,总共为 (O(nlog^2n))

    生成函数

    生成函数的一些运算:

    右移:(F(x)=xF(x)+a_{0}) (最低位一般要手动补一下)

    乘法:(F(x)G(x)=sum_{i=0}^{n-1}sum_{p+q=i}f_{p} imes g_{q})

    导数部分:

    运算规则:

    ([f(x)g(x)]'=f'(x)g(x)+f(x)g'(x))

    (f'(g(x))=f'(g(x))g'(x))

    ([f(x)+g(x)]'=f'(x)+g'(x))

    ([frac{f(x)}{g(x_)}]'=frac{f'(x)g(x)-f(x)g'(x)}{g(x)^2})

    常见导数表:

    (ln'(x)=frac{1}{x})

    ((ax^i)'=a imes i imes x_{i-1})

    ((a^x)'=a^x imes ln a)

    ((e^x)'=e^x)

    ((sin x)'=cos x)

    ((cos x)'=-sin x)

    一些展开

    (frac{1}{1-x}=sum_{i=0}^{infty }x^i)

    (frac{1}{(1-x)^2}=sum_{i=0}^{infty} (i+1)x^i)

    (e^x=sum_{i=0}^{infty} frac{x^i}{i!})

    (ln(1+x)=sum_{i=1}^{infty} (-1)^{i+1}frac{x^i}{i})

    (frac{e^x+e^{-x}}{2}=1+frac{x^2}{2!}+frac{x^4}{4!}+frac{x^6}{6!}+...)

    (frac{e^x-e^{-x}}{2}=x+frac{x^3}{3!}+frac{x^5}{5!}+frac{x^7}{7!}+.....)

    ((1+x)^n=sum_{i=0}^{infty} a^ifrac{x^i}{i!})

    泰勒展开:(f(x)=sum_{i=0}^{infty} frac{f^{(i)}(a)}{i!}(x-a)^i)

    麦克劳林展开:(f(x)=sum_{i=0}^{infty} frac{f^{(i)}(0)}{i!}x^i)

    指数型生成函数

    普通的生成函数一般是不考虑排列顺序的,当我们要将排列顺序考虑进去的时候就要用到指数型生成函数.

    定义:(F(x)=sum_{i=0}^{infty} frac{a_{i}}{i!}x^i)

    其中,(a_{i}) 可以抽象成有 (i) 个物品时的排列数.

    我们将两个指数型生成函数相乘,有:

    (A(x)=F(x)G(x)=sum_{i=0}^{infty} sum_{p+q=i} frac{f_{p}}{p!} imes frac{g_{q}}{q!}x^{p+q})

    然后你发现 (inom{p+q}{q}=inom{p+q}{p}frac{(p+q)!}{p!q!})

    (A(x)=sum_{p+q=i} inom{i}{q}frac{f_{p} imes g_{q}}{i!}x^{i})

    第二类斯特林数

    对于 (S(n,m)) 的理解

    (S(n,m)) 表示将 (n) 个互不相同的元素装进 (m) 个相同盒子,且盒子不能为空的方案数.

    朴素递推:(S(n,m)=S(n-1,m-1)+S(n-1,m) imes m)

    因为盒子不为空,所以第一种情况只能放入最新的盒子,而第二种情况的话 (m) 个盒子可以随便放.

    这个太慢了,考虑二项式反演:

    假设 (n) 固定,我们要求 (S(n,m)) ,则令 (f[k]) 表示钦定 (k) 个盒子为空,其余随便选的方案,(g[k]) 表示恰好.

    则有 (f[k]=inom{m}{k}(m-k)^n=sum_{i=k}^{m}inom{i}{k}g[i])

    反演,得 (g[0]=sum_{i=0}^{m}(-1)^if[i]).

    注意:这里实际上默认将不同得盒子看作不同,所以还要除一个阶乘.

    那么,就有 (S(n,m)=frac{1}{m!}sum_{i=0}^{m}(-1)^iinom{m}{i}(m-i)^n)

    我们把组合数展开,然后约掉最外面的 (frac{1}{m!}) 就会得到:(S(n,m)=sum_{i=0}^{m}frac{(-1)^i}{i!}frac{(m-i)^n}{(m-i)!})

    这个用 NTT 加速多项式乘法来算即可.

    对于 (m^n) 的理解

    这个的组合意义可以看作:将 (n) 个互不相同的小球放入 (m) 个互不相同的盒子的方案数.

    则有 (m^n=sum_{i=0}^{m}inom{m}{i}S(n,i) imes i!)

    这个式子可以理解为:选择 (i) 个盒子不为空,其他的全空,那么不为空就是第二类斯特林数的定义.

    然后从 (m) 个盒子中选出有标号不同的方案数为 (inom{m}{i} imes i!)

    有一些题用这个来拆会更加容易一些.

    这个式子也是比较灵活,也可以写成 (m^n=sum_{i=0}^{n}inom{m}{i}S(n,i) imes i!) 的形式,因为根据组合数和斯特林数的性质,在 (0leqslant ileqslant min(m,n)) 时才会有贡献(否则乘积就是 0 了).

    例题

    FFT/NTT 基础操作

    bzoj 3992

    标签:原根,费马小定理,NTT

    给定数集 (S),求 : 从 (S) 中选择 (n) 个数,使得乘积 mod M 的值为 (x) 的数列有多少个 (?)

    数据范围:$1leqslant n leqslant 10^9,3leqslant M leqslant 8 imes 10^3 $ 且 (M) 为质数 并保证集合中数字小于等于 (M)

    这里的 (N) 非常大,有一个非常好用的套路:用类似于快速幂的方式来计算答案.

    即令 (f[i][j]) 表示长度为 (2^i) 的数列,乘积 mod M = x 的方案数, 然后对 (N) 进行二进制分解,来一遍快速幂

    所以本题的关键在于如何从 (f[i][j]) 推到 (f[i+1][j]) ++++

    易得 (f[i+1][j]=sum_{p,q}f[i][p] imes f[i][q] (p imes qmod M=j))

    如果想用 NTT 优化的话必须要满足和的形式,但是现在是乘积.

    我们直到,如果取对数的 话两个数的乘积可以转换为加法.

    这时候,我们就用上黑科技:原根.

    原根的定义是对于 (g^0....g^{M-2}) 取遍 ([1,M-1]) 的所有值且互不重复.

    那么,我们可以先找原根,然后算出每个数在模意义下的 (log_{g}x) 即对于原根为底的对数.

    而根据费马小定理,有 (a^{qmod (p-1)}=a^q(mod p))

    所以直接以原根为底取对数,然后快速幂的时候用 NTT 优化一下就行.

    但是要注意要将 (M) 后面的项手动加到前面去(我们实现的 NTT 并不是循环卷积)

    bzoj 4332

    标签:分治,FFT

    bzoj 3625

    标签:多项式开根,多项式求逆,生成函数

    构造生成函数 (F,G)

    (F) 的第 (i) 项表示点权之和为 (i) 的二叉树个数,(G) 的第 (i) 项表示集合中是否有 (i) 这个权值.

    然后有 (F[n]=sum_{i=1}^{n}G[i]sum_{j=0}^{n-i}F[j] imes F[n-i-j])

    所以,对于 (F) 的每一项都能被写成 (G*F^2.)

    (F=G*F^2+1) (还要考虑没有节点的情况)

    然后上求根公式:(F=frac{2}{1+sqrt {1-4G}})

    其实那个分母也有可能是 -1,但是这样的话常数项是 0,不存在多项式的逆,所以只能取 +1.

    bzoj 3451

    标签:点分治,FFT,概率期望

    根据期望的线性性,我们算出每个点期望被计算次数,然后进行累加.

    考虑点 (x) 对点 (y) 产生了贡献,那么说明 ((x,y)) 之间的点中 (x) 是第一个被删除的.

    这个期望就是 (frac{1}{dis(x,y)+1}),所以我们只需求 (sum_{i=1}^{n}sum_{j=1}^{n}frac{1}{dis(i,j)+1}) 即可.

    然后这个直接求是求不出来的,所以需要用点分治+FFT来算树上每种距离都出现了多少次.

    第二类斯特林数

    bzoj 4555

    标签:第二类斯特林数,NTT

    (sum_{i=0}^{n}sum_{j=0}^{i}S(i,j) imes 2^j imes (j!))

    不妨将式子化为 (sum_{i=0}^{n}sum_{j=0}^{n}S(i,j) imes 2^j imes (j!)) (反正如果 (j>i) 的话 (S(i,j)=0))

    其中 (S(i,j)) 为第二类斯特林数.

    一般做这种推式子题时如果题面给的式子本身很简洁,那么八成是要把里面的东西暴力展开了.

    展开斯特林数:(S(n,m)=frac{1}{m!}sum_{i=0}^{m}(-1)^iinom{m}{i}(m-i)^n)

    原式可化为 (sum_{i=0}^{n}sum_{j=0}^{n}2^j(j!)sum_{k=0}^{j}frac{(-1)^k}{k!}frac{(j-k)^i}{(j-k)!})

    考虑将 (j) 移到前面,得 (sum_{j=0}^{n}2^j(j!)sum_{k=0}^{j}frac{(-1)^k}{k!}frac{sum_{i=0}^{n}(j-k)^i}{(j-k)!})

    然后上面那个用等比数列求和公式处理,为 (sum_{j=0}^{n}2^j(j!)sum_{k=0}^{j}frac{(-1)^k}{k!}frac{(j-k)^{n+1}-1}{(j-k-1)(j-k)!})

    后面那个是一个卷积的形式,用 NTT 加速即可(等比数列要特判一下公比为 1 的情况)

    bzoj 5093

    标签:第二类斯特林数,NTT

    定义有向图的价值为图中每一个点的度数的 (k) 次方之和.

    求:对于 (n) 个点的无向图所有可能情况的图的价值之和.

    遇到这种题,八成是每个点单独算贡献,然后累加起来.

    我们可以枚举一个点的度数是多少,然后试着去算该情况下的贡献,即 (sum_{i=0}^{n-1}inom{n-1}{i}i^k)

    由于一共有 (n) 个点,而除了我们限定的边之外其余的边都是可以随便连的.

    (Ans=n imes 2^{frac{(n-1)(n-2)}{2}} imes sum_{i=0}^{n-1}inom{n-1}{i}i^k)

    前面的好算,关键在于后面的 (sum_{i=0}^{n-1}inom{n-1}{i}i^k)

    考虑将 (i^k) 按照第二类斯特林数的方式展开,得 (sum_{i=0}^{n-1}sum_{j=0}^{i}S(k,j)inom{i}{j}(j!))

    考虑提前枚举 (j),有 (sum_{j=0}^{n-1}S(k,j)(j!)sum_{i=j}^{n-1}inom{n-1}{i}inom{i}{j})

    后面那个 (sum_{i=j}^{n-1}inom{n-1}{i}inom{i}{j}) 还可以继续推,将组合数变换一下,有 (sum_{i=j}^{n-1}inom{n-1}{j}inom{n-1-j}{i-j})

    (Rightarrow inom{n-1}{j}sum_{i=j}^{n-1}inom{n-1-j}{i-j})

    然后 (sum_{i=j}^{n-1}inom{n-1-j}{i-j}) 的组合意义是从 (n-1-j) 个元素中选择有标号的 (0,1,2...n-1-j) 个元素的方案数.

    这个直接就可以写成 (2^{n-1-j})

    (Ans=n imes 2^{frac{(n-1)(n-2)}{2}}sum_{j=0}^{n-1}S(k,j)(j!)inom{n-1}{j}2^{n-1-j})

    由于 (jleqslant k) 时斯特林数才有意义,所以我们只需枚举到 (min(k,n-1)) 即可.

    斯特林数要用 NTT 来预处理.

    bzoj 2159

    标签:第二类斯特林数,树形dp

    给你一颗树,对于每一个点都求 (S(i)=sum_{j=1}^{N}dist(i,j)^k)(1leqslant N leqslant 50000,1leqslant kleqslant 150)

    没想到第一步就是要把 (dist(i,j)) 给暴力拆开~

    (Rightarrow S(i)=sum_{j=1}^{N}sum_{p=0}^{k}S(k,p)inom{dist(i,j)}{p}p!)

    (Rightarrow S(i)=sum_{p=0}^{k}S(k,p)p!sum_{j=1}^{N}inom{dist(i,j)}{p})

    前一部分的第二类斯特林数可以提前预处理,关键在于后面的 (sum_{j=1}^{N}inom{dist(i,j)}{p})

    这里有一个特别神的转化:由 (inom{n}{m}=inom{n-1}{m}+inom{n-1}{m-1}) 来计算 (inom{dist(i,j)}{p})

    对于 (i) 的儿子来说,到 (i) 儿子的距离就等同于是到 (i) 的距离减 1.

    那么,有(inom{dist(i,j)}{p}=inom{dist(son,j)}{p}+inom{dist(son,j)}{p-1})

    对于子树内的点这么去维护,子树外的用换根 dp 来统计即可.

    洛谷 2791

    标签:第二类斯特林数,NTT

    (sum_{i=0}^{k}inom{m}{i}inom{n-m}{k-i}i^L) ((1leqslant n,mleqslant 2 imes 10^7,1leqslant Lleqslant 2 imes 10^5))

    这个式子比较简洁,然后也没啥可推的,所以我们将 (i^L) 展开.

    那么原式为 (sum_{i=0}^{k}inom{m}{i}inom{n-m}{k-i}sum_{j=0}^{i}inom{i}{j}S(L,j) imes (j!))

    考虑将 (j) 前提,得 (sum_{j=0}^{k}(j!)S(L,j)sum_{i=0}^{k}inom{m}{i}inom{n-m}{k-i}inom{i}{j})

    注意:即使 (i<j) 也是无所谓的,因为后面那个组合数可以帮我们抵消掉.

    我们发现后面的组合数看起来很眼熟,可以考虑对组合数搞点事情.

    (sum_{i=0}^{k}inom{m}{i}inom{n-m}{k-i}inom{i}{j})

    (Rightarrow sum_{i=0}^{k}inom{m}{j}inom{m-j}{i-j}inom{n-m}{k-i})

    (Rightarrow inom{m}{j}sum_{i=0}^{k}inom{m-j}{i-j}inom{n-m}{k-i})

    后面那两个组合数有一个性质:上面的 (n) 之和和下面的 (m) 之和都是定值,所以可以用范德蒙德恒等式

    (Rightarrow inom{m}{j}inom{n-j}{k-j})

    那么最终答案就是 (sum_{j=0}^{k}(j!)S(L,j)inom{m}{j}inom{n-j}{k-j})

    其中斯特林数可以用 NTT 预处理,然后枚举一下 (j) 就好了.

    CF 961G

    标签:第二类斯特林数

    定义一个集合 (S) 的权值 (W(S)=|S|sum_{xin S}w_{x})

    定义一个划分的权值 (W'(R)=sum_{Ssubseteq R}W(S))

    求将 (n) 个物品划分为 (k) 个集合的所有方案的权值和.

    遇到这种求所有方案权值和的题时想都不用想肯定是对每一个元素单独算贡献.

    最开始推了一个比较复杂的计算方法:枚举每个元素所在集合大小. 但是比较繁琐.

    你发现每个元素的贡献是权值 * 集合大小,那么可以理解为:该元素对自己贡献一次,其余所有集合中元素再对自己贡献一次.

    我们考虑每一个元素的系数:

    自己的贡献:(S(n,k))

    其余点的贡献:(S(n-1,k) imes (n-1))

    如果其余元素对该元素有贡献,那么该元素所在集合大小一定要大于 1.

    而我们发现对于其余 (n-1) 个元素都分好的局面来看,其余 ((n-1)) 个点都会对该点贡献一次.

    所以, (Ans=[S(n,k)+S(n-1,k) imes (n-1)]sum_{i=1}^{n}w_{i})

    CF 932E

    标签:第二类斯特林数

    和图的价值几乎是同一道题,没啥营养.

    生成函数

    bzoj 4001

    标签:生成函数,求导,期望

    求:(n) 个点的二叉树叶子个数期望.

    (f_{n}) 表示 (n) 个点所有不同的二叉树叶子总个数,(g_{n}) 表示 (n) 个点不同的二叉树个数.

    则有 (ans=frac{f_{n}}{g_{n}})

    (g_{n}=sum_{i=0}^{n-1}g_{i}g_{n-i-1})

    同时,这个 (g) 的定义就是卡特兰数,所以还有 (g_{n}=frac{inom{2n}{n}}{n+1})

    (G(x)) 表示 (g) 的生成函数,则有 (G(x)=xG(x)^2+1)

    解得 (G(x)=frac{1- sqrt{1-4x}}{x})

    我们将 (G(x)=frac{1+ sqrt{1-4x}}{x}) 舍掉的原因是 (G(0)) 没有任何意义(当验证生成函数的合法性时可以将 0 带入)

    (f_{n}=2 imes sum_{i=0}^{n-1}f_{i}g_{n-i-1})(F(x)=2xF(x)G(x)+x^{1}) (我们向右平移生成函数时会损失掉最低位)

    解得 (F(x)=frac{x}{sqrt{1-4x}})

    得到 (F,G) 的生成函数后,我们要试图寻找 (F,G) 的关系.

    ((xG(x))'=frac{1}{sqrt{1-4x}}=frac{F(x)}{x})

    求完导后,(xG(x)) 的第 (i) 项为 (g_{i} imes (i+1) imes x^{i})

    (frac{F(x)}{x}) 中第 (i) 项为 (f_{i+1} imes x_{i}),故有 (g_{i} imes (i+1)=f_{i+1})

    所以最终答案就是 (frac{g_{n-1} imes n}{g_{n}})

    bzoj 2655

    标签:生成函数

    ([1,A]) 中选择 (n) 个互不相同的数组成一个排列,求所有不同选法乘积之和.

    不妨将排列变为集合,最后再乘上一个 (n!) 即为我们要求的答案.

    构造关于答案的生成函数 (G(x)=prod_{i=1}^{A}(1+ix)),那么 (G) 的第 (i) 项系数就是选 (i) 个数的乘积之和了.

    假如说 (A) 不是很大的话我们可以直接用分治+NTT将答案求出.

    这里 (A) 最多可以达到 (10^9),但是 (n) 却只有 (500) 级别,而我们只想求 (G) 中不大于 (500) 的项数.

    考虑对 (G) 取对数,将乘法变为加法:(G(x)=exp(ln(G(x))))

    (ln G(x)=ln(prod_{i=1}^{A}(1+ix))=sum_{i=1}^{A}ln(1+ix))

    然后根据这个展开:(ln(1+x)=sum_{i=1}^{infty} (-1)^{i+1}frac{x^i}{i}) ,得:

    (ln G(x)=sum_{i=1}^{A}sum_{j=1}^{infty} (-1)^{j+1}frac{i^j}{j}x^j)

    换一下 (i,j) 得顺序,得:(ln(G(x)) =sum_{j=1}^{infty} frac{(-1)^{j+1}sum_{i=1}^{A}x^i}{j}x^j)

    上面那个 (sum_{i=1}^{A}x^i) 可以用卡个朗日插值与处理一下,然后最后再取一个多项式 (exp) 就行了.

    poj 3734

    标签:指数型生成函数,常见展开

    题意:有红球,蓝球,绿球,黄球,其中红球和绿球都只能选择偶数个,求选择 (n) 个球摆成一排有多少种方案数.

    我们构造关于这些球的指数型生成函数 (F(x)=sum_{i=0}^{infty} frac{a_{i}}{i!}x^i) 其中 (a_{i}) 表示选择 (i) 个球的不同排列数.

    红与绿:(1+frac{x^2}{2!}+frac{x^4}{4!}+.....=frac{e^x+e^{-x}}{2})

    黄与蓝:(1+frac{x}{1!}+frac{x^2}{2!}+......=e^x)

    那么 G+R+Y+B (=(frac{e^x+e^{-x}}{2})^2(e^{x})^2)

    把这个再展开,然后我们发现第 (n) 项系数为 (frac{4^n+2^{n+1}}{n!}),故答案为 (4^n+2^{n+1})

    洛谷 4389

    标签:生成函数,多项式 exp

    题意:一共有 (n) 个物品,每件物品体积为 (v_{i}),数量为 (10^5),求:装满一个容量为 (m) 的背包有多少种不同方案.

    比较友好的生成函数,并不是很难推导(似乎有些套路QAQ)

    对于每一件物品列生成函数 (F_{i}(x)=sum_{i=0}^{infty} [i\%v=0]x^i),则 (Ans=prod_{i=1}^{n}F_{i}(x))

    对于 (F_{i}(x)),有 (F_{i}(x)=sum_{i=0}^{infty} (x^v)^i=frac{1}{1-x^v})

    所有有 (Ans=prod_{i=1}^{n}frac{1}{1-x^{v_{i}}})

    我们发现这个东西很难处理,因为这是 (n) 个多项式相乘.

    那么我们这个时候九有一个常用的套路:对多项式取 (ln),将乘法 $Rightarrow $ 加法(因为多项式加法比较简单,而乘法涉及卷积)

    (ln Ans=ln prod_{i=1}^{n}frac{1}{1-x^{v_{i}}}=sum_{i=1}^{n}ln (frac{1}{1-x^{v_{i}}}))

    然后又有一个套路:(ln(1+x)=sum_{i=1}^{infty} (-1)^{i+1}frac{x^i}{i}) ,所以我们试着将 (ln) 中的分数提出.

    (Rightarrow ln frac{1}{1-x^{v_{i}}}=-ln (1-x^{v_{i}}))

    (Rightarrow ln Ans=-sum_{i=1}^{n}ln (1-x^{v_{i}}))

    (Rightarrow ln(Ans)=sum_{j=1}^{n}sum_{i=1}^{infty}frac{x^{v_{j}i}}{i})

    利用调和级数来记录每个物品的贡献,然后最后再求一个多项式 (exp) 就好了.

    洛谷 5162

    标签:指数型生成函数,多项式求逆

    感觉这个生成函数还是蛮有难度的.

    每一层的指数型数的生成函数 (F(x)=sum_{i=1}^{infty} frac{1}{i!}x^i)

    那么所有层的生成函数就是 (G(x)=sum_{i=1}^{infty} F^i(x))

    我们注意到因为这道题划分规则比较奇特,所以我们在 (G(x)) 的生成函数那里不用除阶乘.

    (Rightarrow sum_{i=1}^{infty} F^i(x)=sum_{i=0}^{infty} F^i(x)-F^0(x)=frac{1}{1-F(x)}-1)

    所以这个分母直接这么求就好了,分子同理.

    但是呢,我们发现一个严重的问题:指数型生成函数中那个 (n) 次项系数还需要乘上一个阶乘.

    我们可以证明分子和分母没有出现 (n! imes a_{n}+b_{n}) 的情况,所以那个阶乘可以直接抵消.

    洛谷 5860

    标签:生成函数,多项式exp

    (n) 个点,每个点有一个度数 (v[i]),代表如果选择这个点就必须满足这个点与 (v[i]) 条边相连.

    求:有多少种选法,使得所选集合中的点能构成一棵树.

    如果 (m) 个点能生成一颗树,那么一定满足 (sum v_{i}=2 imes (m-1))

    这是因为度数之和其实就是边的数量 ( imes 2).

    然后感性理解:如果 (m) 个点满足 (sum v_{i}=2 imes(m-1)),则一定能构成一棵树.

    那就将问题转化成:有 (m) 个物品,每个物品的价值为 (v_{i}-2),求装满一个体积为 (-2) 的背包有多少种选法.

    对于所有 (v_{i}-2>0) 的部分,我们直接设生成函数+多项式 exp 来做,然后 (v_{i}=2) 的部分直接乘上贡献.

    最后 (v_{i}=1) 的部分直接来一个二项式定理展开,然后依次枚举 (v_{i}=1) 的个数就好了.

    因为有 (ori-i=-2),所以有 (ori=i-2).

    单位根反演

    LOJ 6485

    标签:单位根反演,二项式定理

    (sum_{i=0}^{n}inom{n}{i}s^ia_{imod 4})

    (1leqslant)所有元素 (leqslant 10^{18})

    (Rightarrow sum_{j=0}^{3}a_{j}sum_{i=0}^{n}inom{n}{i}s^i[imod 4=j])

    然后用单位根反演替换那个特判

    (Rightarrow sum_{j=0}^{3}a_{j}sum_{i=0}^{n}inom{n}{i}s^ifrac{1}{4}sum_{k=0}^{3}w_{k}^{(i-j)k})

    (Rightarrow frac{1}{4} sum_{j=0}^{3}a_{j}sum_{k=0}^{3}sum_{i=0}^{n}inom{n}{i}s^iw_{k}^{(i-j)k})

    然后有一个常见的套路:你发现后面那个 (sum_{i=0}^{n}inom{n}{i}s^iw_{k}^{(i-j)k}) 特别像二项式展开,那我们逆着整成 (n) 的次幂形式即可. ‘

    bzoj 3328

    标签:单位根反演,二项式定理,矩阵乘法

    和前面的那道题挺像的,只不过这里 ((x+y)^n) 中的 (x,y) 不再是整数,而是矩阵,需要写一个矩阵乘法.

    牛客 73E

    标签:单位根反演,二项式定理,NTT

    和前面不一样的是这道题需要用 NTT 再把值给带回去,也不是很难.

    拉格朗日插值

    51nod 1258

    标签:拉格朗日插值,找规律

    (sum_{i=1}^{n}i^k)

    (f(n)=sum_{i=1}^{n}i^k),这是一个 ((k+1)) 次的多项式,所以随便选 (k+1) 个点往里带然后拉格朗日插值一下即可.

  • 相关阅读:
    对两个有序数组进行合并
    连续子数组的最大和问题
    设计模式的学习
    Android基础总结(12)——XML和JSON解析
    Android基础总结(8)——服务
    x64 Assembly Tutorial 1 : Getting into x64 ASM from C++
    C# IL 指令集
    Unity3D教程宝典之地形
    Unity3D 动态改变地形 Unity3D Dynamic Change Terrain
    C#中String.format用法详解
  • 原文地址:https://www.cnblogs.com/guangheli/p/11885107.html
Copyright © 2011-2022 走看看