zoukankan      html  css  js  c++  java
  • 多项式&生成函数

    多项式和生成函数

    Warning: 它很基础,请( ext{dalao})勿喷.

    多项式

    鸽掉了多项式开根(加强版).

    这里放一份多项式板子合集

    多项式乘法

    背个板子就好了.

    FFT

    MTT

    泰勒展开与麦克劳林级数

    (f(x))(x=x0)处存在(n)阶导,那么:

    [egin{align} f(x)&=f(x0)+frac{f^1(x0)}{1!}(x-x0)+frac{f^2(x0)}{2!}(x-x0)^2+...+frac{f^n(x0)}{n!}(x-x0)^n+xi\ &=sum_{i=0}^nfrac{f^i(x0)}{i!}(x-x0)^i+xi end{align} ]

    (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)) equiv 0( ext{mod} x^n) ]

    例如 如果要求逆,那么(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))处泰勒展开,有:

    [F(B_{2n}(x))=F(B_n(x))+frac{F'(B(x))}{1!}(B_{2n}(x)-B_n(x))+... ]

    此时我们发现后面的项都是没有用的,因为:

    [F(B_{2n}(x))equiv 0( ext{mod }x^{n}) ]

    然后不难发现,(B_{2n}(x))的后(n)项和(B_n(x))没有区别,那么当变成((B_{2n}-B_n(x))^2)的时候就会把它全部覆盖,所以此时一定满足(F(B_{2n}(x)))的性质,也就是( ext{mod }x^nequiv 0).

    这个时候我们把式子化成了:

    [B_{2n}(x)=B_n(x)-frac{F(B_n(x))}{F'(B_n(x))} ]

    注意求导是对(B_n(x))求导.然后就可以递归求解了.

    多项式求逆

    (F(B_n(x))=A(x)*B_n(x)-1 equiv 0).

    那么此时可以得到:

    [egin{align} B_{2n}(x)&=B_n(x)-frac{A(x)*B_n(x)-1}{A(x)}\ &=B_n(x)-(A(x)*B_n(x)-1)B_n(x)\ &=2B_n(x)-A(x)*B^2_n(x) end{align} ]

    多项式开根

    (F(B_n(x))=B_n^2(x)-A(x)equiv 0)

    此时可以得到:

    [egin{align} B_{2n}(x)&=B_n(x)-frac{B_n^2(x)-A(x)}{2B_n(x)}\ &=frac{1}{2}(frac{B^2_n(x)+A(x)}{B_n(x)})\ &=frac{1}{2}(B_n(x)+frac{A(x)}{B_n(x)}) end{align} ]

    需要用到多项式求逆.

    多项式求导

    ((x^n)'=n*x_{n-1}),导数具有线性性,直接算即可.

    多项式积分

    (int x^n=frac{1}{n+1}x^{n+1}),同样满足线性性.

    多项式ln

    [ln(A(x))=B(x)\ ln'(A(x))=B'(x)\ frac{A'(x)}{A(x)}=B'(x) ]

    直接复合函数求导之后求导+乘法( o)积分即可.

    多项式exp

    看到这里应该没有人不知道(exp(x))(e^x)吧.
    (F(B_n(x))=ln B_n(x)-A(x)equiv 0)

    [egin{align} B_{2n}(x)&=B_n(x)-frac{ln B_n(x)-A(x)}{frac{1}{B_n(x)}}\ &=B_n(x)-B_n(x)(ln B_n(x)-A(x))\ &=B_n(x)(1-ln B_n(x)+A(x)) end{align} ]

    要套用多项式(ln)和多项式乘法.

    多项式快速幂

    [B(x)=A^k(x)\ ln B(x)=kln A(x) ]

    直接取(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)多项式的系数.

    那么这个时候有:

    [A(x)=B(x)*C(x)+R(x)\ A(frac{1}{x})=B(frac{1}{x})*C(frac{1}{x})+R(frac{1}{x})\ x^nA(frac{1}{x})=x^mB(frac{1}{x})*x^{n-m}C(frac{1}{x})+x^nR(frac{1}{x})\ A^R(x)=B^R(x)*C^R(x)+R^R(x)*x^{n-m+1} ]

    然后把这个式子在(mod x^{n-m+1}),就是:

    [A^R(x)=B^R(x)*C^R(x)\ C^R(x)=frac{A^R(x)}{B^R(x)} ]

    直接套用多项式求逆即可.
    (R(x)=A(x)-B(x)*C(x)),直接计算即可.

    其他

    补坑.

    分治FFT

    纯粹的分治(FFT),不是(cdq)那套理论,求(prod_{i=1}^n(1+a_ix)).

    考虑分治然后合并即可.

    套路

    (sum_{i=1}^na_i^t)

    LuoguP4705 玩游戏

    首先考虑上面的分治(FFT)求出来的东西,令它为(F(x)),有:

    [egin{align} ln F(x)&=sum_{i=1}^n ln (1+a_ix)\ &=sum_{i=1}^n frac{a_i}{1+a_ix}\ &=sum_{i=1}^n sum_{j=0}^{infty} -1^{j}a_i^{j+1}x^j\ &=sum_{j=0}^{infty} -1^j sum_{i=1}^n a_i^{j+1} x^j end{align} ]

    第二步和第三步的转换是无穷等比数列求和公式倒推.

    只要把对应项取负数然后就变成了(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|)个位置.

    考虑一个卷积,有:

    [F(x)=sum_{i=1}^{|T|}|S_{x+i-1}-T_{i}| ]

    如果对于一个位置(x),有(F(x)=0),那么就会有匹配是吧.

    看到这个绝对值感觉很不好搞,平方拆掉.

    [egin{align} F(x)&=sum_{i=1}^{|T|}(S_{x+i-1}-T_{i})^2\ &=sum_{i=1}^{|T|}{S_{x+i-1}}^2+{T_i}^2-2S_{x+i-1}T_i end{align} ]

    唯一的问题在于后面的(x+i-1)(i)的和不恒定,考虑将(T)串翻转,有:

    [S_{x+i-1}T_i=S_{x+i-1}T_{|T|-i+1} ]

    此时有(x+i-1+|T|-i+1=x+|T|).这是一个只和(x)有关的东西,好.

    这个时候发现只有卷积是要算的,第一个可以前缀和,第二个是常数.

    这个时候卷就行了.

    带通配符的匹配

    T串有

    考虑上文我们已经求出来了一般的匹配,这个时候添加了一个通配符,可以匹配任意一个字符,那么有:

    [egin{align} F(x)&=sum_{i=1}^{|T|}(S_{x+i-1}-T_{i})^2T_i\ &=sum_{i=1}^{|T|}{S_{x+i-1}}^2T_i+T_i^3-2T_i^2S_{x+i-1} end{align} ]

    这就变成了两个卷积+一个常数的形式.

    代码

    S和T串都有

    同样的,将(S)对应乘进去.

    [egin{align} F(x)&=sum_{i=1}^{|T|}(S_{x+i-1}-T_{i})^2T_iS_{x+i-1}\ &=S_{x+i-1}^3T_i+T_i^3S_{x+i-1}-2T_i^2S_{x+i-1}^2 end{align} ]

    三个卷积直接做即可,美哉.

    代码

    加速计算

    这里主要是以列举一些题目为主.

    [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]力

    还是一样的:

    [E_i=frac{F_i}{q_i}=sum_{j=1}^{i-1}frac{q_j}{(i-j)^2}-sum_{j=i+1}^nfrac{q_j}{(i-j)^2} ]

    考虑令(f_i=q_j,g_i=frac{1}{i^2}),就可以写成:

    [E_i=sum_{j=1}^{i-1}g_{j-i}f_i-sum_{j=i+1}^ng_{j-i}f_i ]

    看到后面的不是从(1)开始很不爽,翻转一下然后答案就是两个卷积的差.

    上面两道题目都是用多项式快速计算乘积.


    [HEOI2016/TJOI2016]求和

    很简单,就是考第二类斯特林数怎么快速求.

    [egin{align} egin{Bmatrix}n\kend{Bmatrix}&=frac{1}{k!}sum_{i=0}^n(-1)^iinom{k}{i}(k-i)^n\ &=sum_{i=0}^nfrac{-1^{i}}{i!}frac{(k-i)^n}{(k-i)!} end{align} ]

    这就可以(NTT)了.

    上面这题使用多项式快速求出第一类/第二类斯特林数.

    关于怎么求,可以看我博客关于斯特林数的总结.


    [SDOI2015]序列统计

    首先考虑最暴力的转移,设(f_{i,j})表示前(i)个数,乘积为(j)的方案数:

    [f_{2*i,c}=sum_{a*bmod m=c}f_{i,a}f_{j,b} ]

    如果要写成卷积的形式,显然要把乘法变成加法,考虑取(ln),有:
    (f_{2*i,c}=sum_{a+b mod c}f_{i,a}f_{j,b})
    然后直接快速幂卷积即可,注意取(ln)要算原根.
    具体一点可以看这篇文章


    生成函数

    这是一个令人自闭的环节,我这种菜鸡根本想不到怎么做题.当然如果像yyb一样强就不用了.

    图的计数
    首先就是注意一点,有标号和无标号分别对应着(EGF)(OGF),因为(EGF)下面多除了一个(i!),对应就要乘回去一个(i!),然后就是排列,(OGF)就是组合.

    [集训队作业2013]城市规划

    考虑令(i)个点的答案为(f_i),则(f_i)表示(i)个点的无向连通图个数.

    考虑设(g_i)表示(i)个点的连通图个数,则(g_i=2^{inom{i}{2}}).

    然后枚举(1)号点的连通块大小,有:

    [g_n=sum_{i=1}^ninom{n-1}{i-1}f_ig_{n-i} ]

    表示这个是无向连通图,剩下的随便选.

    然后将组合数拆开,发现是一个卷积的形式,每一项是一个(EGF).

    直接求逆,卷完之后乘(fac[n-1])即可.

    背包问题

    Luogu4389 付公主的背包

    首先发现题目要求的是完全背包的方案数,考虑一个物品的贡献:

    [sum_{i=0}^{infty}[i\%V==0]x^{i}=frac{1}{1-x^{V}} ]

    现在答案变成了:(prod_{i=1}^mfrac{1}{1-x^{V_i}})

    发现这个(prod)不是很好求,考虑变成(ln)之后就可以求和了.

    [sum_{i=0}^{infty}[i\%V==0]x^{i}=frac{1}{1-x^{V}} ]

    现在答案变成了:(prod_{i=1}^mfrac{1}{1-x^{V_i}})

    发现这个(prod)不是很好求,考虑变成(ln)之后就可以求和了.

    以下推导省略(dx),把(ln frac{1}{1-x^V}=-ln{(1-x^V)}):

    [egin{aligned} F(x)&=int F'(x)=int frac{-Vx^{V-1}}{1-x^V}\ &=int -Vx^{V-1}(sum_{i=0}^{infty}x^{Vi})\ &=-int sum_{i=0}^{infty}Vx^{V(i+1)-1}\ &=-sum_{i=1}^{infty}frac{x^{Vi}}{i} end{aligned} ]

    考虑可以求每一个(V)的贡献,然后开个桶记一下就行了.

    参考

    ( ext{cjyyb})的生成函数总结
    ( ext{zhoushuyu})的多项式总结

  • 相关阅读:
    webStorm 快捷键 + 浏览器
    Linux安装nodejs和npm
    jQuery页面滚动底部加载数据
    html跳转指定位置-利用锚点
    JavaScript自定义对象
    vue v-time指令封装(接口返回时间戳 在到日期转换)
    vue 之 引入elementUI(两步走)
    小白6步搞定vue脚手架创建项目
    vue 封装组件
    npm dev run 报错
  • 原文地址:https://www.cnblogs.com/fexuile/p/12289196.html
Copyright © 2011-2022 走看看