多项式和生成函数
Warning: 它很基础,请( ext{dalao})勿喷.
多项式
鸽掉了多项式开根(加强版).
多项式乘法
背个板子就好了.
泰勒展开与麦克劳林级数
若(f(x))在(x=x0)处存在(n)阶导,那么:
(xi)是余项,当(n)无穷大时(xi)为高阶无穷小.
特殊情况是(x0=0)是的泰勒展开,称之为麦克劳林级数.
(f(x)=sum_{i=0}^nfrac{f^i(0)}{i!}x^i)
比较常见的是(e^x)的展开:(e^x=1+frac{x}{1!}+frac{x^2}{2!}+frac{x^3}{3!}+...)
牛顿迭代
一个很有用的东西.
我们知道任何一种多项式运算都可以变成一种运算(F(x))和一个多项式(B(x)),满足
例如 如果要求逆,那么(F(B(x))=A(x)*B(x)-1 equiv 0)
现在考虑当(n=1)的时候很好求是吧.
考虑用(n)扩展到(2n)的情况:令(B_{n}(x))表示满足(n)的解.
将(F(B_{2n}(x)))在(B_n(x))处泰勒展开,有:
此时我们发现后面的项都是没有用的,因为:
然后不难发现,(B_{2n}(x))的后(n)项和(B_n(x))没有区别,那么当变成((B_{2n}-B_n(x))^2)的时候就会把它全部覆盖,所以此时一定满足(F(B_{2n}(x)))的性质,也就是( ext{mod }x^nequiv 0).
这个时候我们把式子化成了:
注意求导是对(B_n(x))求导.然后就可以递归求解了.
多项式求逆
(F(B_n(x))=A(x)*B_n(x)-1 equiv 0).
那么此时可以得到:
多项式开根
(F(B_n(x))=B_n^2(x)-A(x)equiv 0)
此时可以得到:
需要用到多项式求逆.
多项式求导
((x^n)'=n*x_{n-1}),导数具有线性性,直接算即可.
多项式积分
(int x^n=frac{1}{n+1}x^{n+1}),同样满足线性性.
多项式ln
直接复合函数求导之后求导+乘法( o)积分即可.
多项式exp
看到这里应该没有人不知道(exp(x))是(e^x)吧.
(F(B_n(x))=ln B_n(x)-A(x)equiv 0)
要套用多项式(ln)和多项式乘法.
多项式快速幂
直接取(ln)然后每一个系数乘再做一个(exp)即可.
多项式除法
给定一个长度为(n)的多项式(A(x)),一个长度为(m)的多项式(B(x)),求一个长度为(n-m)的多项式(C(x))和一个长度小于(n-m)的多项式(R(x)).
首先我们定义一个运算(Reverse)为(A^R(x)=x^nA(frac{1}{x})),其实就等于翻转(A)多项式的系数.
那么这个时候有:
然后把这个式子在(mod x^{n-m+1}),就是:
直接套用多项式求逆即可.
(R(x)=A(x)-B(x)*C(x)),直接计算即可.
其他
补坑.
分治FFT
纯粹的分治(FFT),不是(cdq)那套理论,求(prod_{i=1}^n(1+a_ix)).
考虑分治然后合并即可.
套路
求(sum_{i=1}^na_i^t)
首先考虑上面的分治(FFT)求出来的东西,令它为(F(x)),有:
第二步和第三步的转换是无穷等比数列求和公式倒推.
只要把对应项取负数然后就变成了(a_i^{j+1})了.因为求的是(j+1)项,所以只需要注意(sum_{i=1}^na_i^0=n).
看完上面的你就可以去做多项式板子了
但是那个开根要用二次剩余,他不保证(a[0]=1).
生成函数
普通型生成函数(( ext{OGF}))
考虑一个数列(A=<a_0,a_1,a_2,...>),他的( ext{OGF})是(a_0+a_1x+a_2x^2+...)
例如斐波那契数列的( ext{OGF})就是(0+1x+1x^2+2x^3+...)
指数型生成函数(( ext{EGF}))
对于数列(a),他的( ext{EGF})是(sum_{i=0}^{infty}frac{a_i}{i!}x^i)
(e^x)的就是数列(<1,1,1,1,...>)的(EGF).
题目
关于字符串的问题
回文串
首先是关于回文串,考虑回文串中一对对称的字符:(S[x+a]=S[x-a]),那么他们的下标和确定对吧.
(x+a+x-a=2x),所以(FFT)之后直接查下标([1,2n])范围内的即可.
一般匹配
KMPtxdy
匹配倒也是一个比较神奇的东西,考虑我们要找到某些位置(k)令(T)串能覆盖(k)及后面(|T|)个位置.
考虑一个卷积,有:
如果对于一个位置(x),有(F(x)=0),那么就会有匹配是吧.
看到这个绝对值感觉很不好搞,平方拆掉.
唯一的问题在于后面的(x+i-1)和(i)的和不恒定,考虑将(T)串翻转,有:
此时有(x+i-1+|T|-i+1=x+|T|).这是一个只和(x)有关的东西,好.
这个时候发现只有卷积是要算的,第一个可以前缀和,第二个是常数.
这个时候卷就行了.
带通配符的匹配
考虑上文我们已经求出来了一般的匹配,这个时候添加了一个通配符,可以匹配任意一个字符,那么有:
这就变成了两个卷积+一个常数的形式.
同样的,将(S)对应乘进去.
三个卷积直接做即可,美哉.
加速计算
这里主要是以列举一些题目为主.
[AH2017/HNOI2017]礼物
考虑题目要求的是(sum_{i=1}^n(a_i-b_i+x)^2 x in [-m,m]).
这个式子拆开之后枚举(x),发现只有(sum_{i=1}^na_ib_i)要求最大值.
直接(reverse)后(FFT)即可.
[ZJOI2014]力
还是一样的:
考虑令(f_i=q_j,g_i=frac{1}{i^2}),就可以写成:
看到后面的不是从(1)开始很不爽,翻转一下然后答案就是两个卷积的差.
上面两道题目都是用多项式快速计算乘积.
[HEOI2016/TJOI2016]求和
很简单,就是考第二类斯特林数怎么快速求.
这就可以(NTT)了.
上面这题使用多项式快速求出第一类/第二类斯特林数.
关于怎么求,可以看我博客关于斯特林数的总结.
[SDOI2015]序列统计
首先考虑最暴力的转移,设(f_{i,j})表示前(i)个数,乘积为(j)的方案数:
如果要写成卷积的形式,显然要把乘法变成加法,考虑取(ln),有:
(f_{2*i,c}=sum_{a+b mod c}f_{i,a}f_{j,b})
然后直接快速幂卷积即可,注意取(ln)要算原根.
具体一点可以看这篇文章
生成函数
这是一个令人自闭的环节,我这种菜鸡根本想不到怎么做题.当然如果像yyb一样强就不用了.
图的计数
首先就是注意一点,有标号和无标号分别对应着(EGF)和(OGF),因为(EGF)下面多除了一个(i!),对应就要乘回去一个(i!),然后就是排列,(OGF)就是组合.
考虑令(i)个点的答案为(f_i),则(f_i)表示(i)个点的无向连通图个数.
考虑设(g_i)表示(i)个点的连通图个数,则(g_i=2^{inom{i}{2}}).
然后枚举(1)号点的连通块大小,有:
表示这个是无向连通图,剩下的随便选.
然后将组合数拆开,发现是一个卷积的形式,每一项是一个(EGF).
直接求逆,卷完之后乘(fac[n-1])即可.
背包问题
首先发现题目要求的是完全背包的方案数,考虑一个物品的贡献:
现在答案变成了:(prod_{i=1}^mfrac{1}{1-x^{V_i}})
发现这个(prod)不是很好求,考虑变成(ln)之后就可以求和了.
现在答案变成了:(prod_{i=1}^mfrac{1}{1-x^{V_i}})
发现这个(prod)不是很好求,考虑变成(ln)之后就可以求和了.
以下推导省略(dx),把(ln frac{1}{1-x^V}=-ln{(1-x^V)}):
考虑可以求每一个(V)的贡献,然后开个桶记一下就行了.