zoukankan      html  css  js  c++  java
  • 「笔记」多项式乱写


    没什么干货,基本上都是瞎写,而且是想到什么写什么,所以可能你看完也学习不到什么。

    由于我数学很差,所以可能会写大堆废话 + 大堆错误 + 大堆不带证明的结论。

    对之前多项式(生成函数)相关内容做个整理,之前的垃圾博客都隐藏了。

    由于我水平有限,所以写的东西比较显然,内容也十分基础入门。

    大部分算法只限于口胡而没有实现过,所以不保证正确性。


    请问生成函数该怎么定义啊.jpg

    如果按照函数去理解,你会发现我们几乎没有管敛散性,然而这并不严谨。

    如果按照形式幂级数的方式去定义,你需要手动验证如 (exp,ln,int,frac{dy}{dx}) 满足它们该有的性质(尽管来说这是可以做到的,丢一个链接就逃)。

    放弃思考它的正确性,感觉该怎么做就怎么做吧。


    mtt

    不太想再写一遍 fft 相关教程,就写个 mtt 的做法吧。

    (S = lfloorsqrt{M} floor),可以把系数 (a_i) 拆成 (lfloorfrac{a_i}{S} floor)(a_i mod S),这样正变换四次,逆变换三次即可,且精度也有保证。

    将两次正变换缩成一次的优化:如果当前有两个实系数多项式 (A(x), B(x)) 要正变换,可以转化成 (P(x)=A(x)+iB(x),Q(x) =A-iB(x)) 正变换。

    考虑可否知 (Q)(P)(以下记 (overline{z}) 表示 (z) 的共轭,记 (hat{Q}_j) 表示 (Q(omega_{n}^{j}))):

    [hat Q_j=sum_{k=0}^{n-1}(a_k-ib_k) imesomega_{n}^{jk} = sum_{k=0}^{n-1}overline{(a_k+ib_k)} imesoverline{omega_{n}^{(n-j)k}} =sum_{k=0}^{n-1}overline{(a_k+ib_k) imes omega_{n}^{(n-j)k}}=overline{hat P_{n-j}} ]

    然后考虑逆变换是否也可以两次缩一次:(hat R_j = hat A_j + ihat B_j),则逆变换后 (r_j = a_j + ib_j)。由于 (A(x),B(x)) 都是实系数,所以直接取实虚部对应系数即可。

    这样的话只需做 4 次(严格来说只需做 3.5 次——假如你需要做多次卷积,可以把单出来的逆变换放一起做)。


    牛顿迭代

    事实上,牛顿迭代一般是用来解方程的数值解而非方程的封闭解。

    attention:以下记 (z) 为形式幂级数的元,记 (x)(z) 的幂级数(即 (x = f(z)),其中 (f) 是个多项式)。

    解方程 (F(x)=0)(一般来说是在 (mod z^{n}) 意义下),基础思想为倍增,即根据 (mod z^n) 的解 (x_0) 求出 (mod z^{2n}) 的解 (x)

    注意到 (x = x_0 mod z^n),因此有 ((x-x_0)^2 = 0mod z^{2n}),也即 ((x-x_0)^k=0mod z^{2n},k>1)

    考虑将 (F(x))(x_0) 处泰勒展开得 (F(x) = sum_{i=0}^{infin}frac{F^{(i)}(x_0)}{i!}(x-x_0)^i=0mod z^{2n})。注意这里的求导是对 (x) 求导,因此会有 (frac{dA(z)}{dx}=0)

    由上可知 (F(x) = F(x_0) + F'(x_0)(x-x_0)=0mod z^{2n}),变形得到 (x=x_0-frac{F(x_0)}{F'(x_0)} mod z^{2n})(即牛顿迭代的式子)。

    这里的复杂度瓶颈在于计算 (frac{F(x_0)}{F'(x_0)})(实际上在做多项式复合)。


    几个经典应用:

    (1)求逆,即解方程 (F(x) = frac{1}{x} - A(z) = 0)(方程 (A(z)x-1=0) 虽然也正确,但是用牛迭解不出来),牛迭式为 (x=2x_0-A(z)x_0^2)

    (2)求 (ln)(尽管它并不是用牛迭做),(ln A(z)=int frac{A'(z)}{A(z)}dz),求逆即可。

    (3)求 (exp),即解方程 (ln x - A(z)=0),牛迭式为 (x=x_0-(ln x_0-A(z))x_0)

    (4)求幂,(A^k(z)=exp(k imesln A(z)))(如果多项式系数是在模意义下运算,(k) 直接对模数取模——这里和费马小定理/欧拉定理扯不上关系)。

    (5)求一阶微分方程,即解方程 (frac{dx}{dz}=F(x))(其实这个难点主要在于微积分的技巧),牛迭到某一步时有 (frac{dx}{dz}=F(x_0)+F'(x_0)(x-x_0)mod z^{2n})

    即解方程 (frac{dx}{dz}-F'(x_0)x=F(x_0)-F'(x_0)x_0)接着随便翻开本微积分教材 构造 (P(x_0) = e^{int F'(x_0)dz})(还是注意这里的 (F'(x_0)) 是对 (x) 求导):

    [egin{aligned} frac{dx}{dz}-xF'(x_0)=frac{1}{P(x_0)}left(frac{dx}{dz}P(x_0)- xF'(x_0)P(x_0) ight)=frac{1}{P(x_0)}frac{d(xP(x_0))}{dz} end{aligned} ]

    而等式右边是常数,就可以继续解了。

    以上例子时间复杂度都是 (O(sum_{i=0}frac{n}{2^i}log frac{n}{2^i}) = O(nlog n))


    拉格朗日反演

    attention:以下记 (z) 为形式幂级数的元,记 (x)(z) 的幂级数(即 (x = f(z)),其中 (f) 是个多项式)。

    attention:以下记 (F^{-1}(z))(F(z)) 的复合逆,而将 (F(z)) 的乘法逆写作 (frac{1}{F(z)})

    我们只考虑常数项为 0,一次项为 1 的形式幂级数,这些幂级数在复合运算下形成群,所以 (forall F(z),exist F^{-1}(z),F^{-1}(F(z)) = F(F^{-1}(z)) = z)

    求复合逆 (F^{-1}(z)) 可以根据定义列方程牛顿迭代,或者参考下面 “多项式复合” 部分。当然一般来说,最常用的是拉格朗日反演。

    先说明,我们将形式幂级数的环扩成了分式环,所以才能定义出常数项为 0 的幂级数的乘法逆,如 (z^{-1})

    拉格朗日反演告诉我们 ([z^n]F^{-1}(z)=frac{1}{n}[z^{-1}](frac{1}{F^n(z)})),有一个更常用的形式是 ([z^n]F^{-1}(z)=frac{1}{n}[z^{n-1}](frac{z}{F(z)})^n)

    扩展拉格朗日反演告诉我们 ([z^n]H(F^{-1}(z)) = frac{1}{n}[z^{-1}]H'(z)(frac{1}{F^n(z)})),同上,更常用的形式是 ([z^n]H(F^{-1}(z)) = frac{1}{n}[z^{n-1}]H'(z)(frac{z}{F(z)})^n)

    证明:

    (F^{-1}(z)=sum a_iz^i),则 (sum a_i F^i(z) = z)

    两边对 (z) 求导,得 (sum ia_i F^{i-1}(z)F'(z)=1)

    两边同除以 (F^n(z)),得 (sum a_i F^{i-n-1}(z)F'(z)=frac{1}{F^n(z)})

    (i ot = n) 时,([x^{-1}]ia_iF^{i-n-1}(z)F'(z)=[x^{-1}]frac{ia_i}{i-n}(F^{i-n})'(x)=0)(幂函数求导不可能出现 (x^{-1}))。

    (i = n) 时,([x^{-1}]na_nfrac{F'(z)}{F(z)}=[x^{-1}]na_nfrac{F'(z)}{z} imesfrac{z}{F(z)}=na_n)(注意 (F(z)) 常数项为 0 且一次项为 1)。

    因此有 (a_n=frac{1}{n}[x^{-1}]frac{1}{F^n(z)})。扩展形式基本一样,只是把一开始等式右边的 (z) 替换成了 (H(z))

    考虑对二元函数 ([z^n](frac{1}{1-uF(z)})) 作拉格朗日反演得到 (frac{1}{n}[z^{n-1}](frac{1}{1-uz})'(frac{z}{F^{-1}(z)})^n)

    左边即 ([z^n]F(z), [z^n]F^2(z),dots [z^n]F^n(z))。如果复合逆很好求,那么就可以快速算出前面的东西。

    据说很有用。


    杂项

    带余除法

    请问为什么要对 “带鱼” 做除法。

    形式幂级数是欧式环 (Leftrightarrow) 形式幂级数可做带余除法。

    (F(x)=sum_{i=0}^{n-1}f_ix^i),则记 (degF=n-1)

    给定 (A(x), B(x)),我们想找到 (P(x),R(x)) 满足 (degR<degB)(A(x)=B(x)P(x) + R(x))。可以发现此时有 (degP=degA-degB)

    考虑变换 (A_r(x) = x^{degA}A(x^{-1})),即把 (A) 的系数翻转得到 (A_r(x))

    对上述等式做该变换得到 (A_r(x)=B_r(x)P_r(x)+R_r(x)x^{degA-degB+1}),对 (x^{degA-degB+1}) 取模转化成多项式求逆,求出 (P(x)) 后作减法即得 (R(x))


    多点求值(旧)

    如果想对 (x_1,x_2dots x_n) 求值,可以分治先算出 (P_L(x)=prod_{i=1}^{mid}(x-x_i))(P_R(x)=prod_{i=mid+1}^{n}(x-x_i))

    由于 (forall iin[1,mid],P_L(x_i)=0),所以 (forall iin[1,mid],A(x_i) = (A mod P_L)(x_i)),同理 (forall iin[mid+1,n],A(x_i)=(Amod P_R)(x_i))

    于是分治即可,时间复杂度 (O(nlog^2 n))

    一个小应用:求范德蒙行列式 (prod_{1leq j < i leq n}(x_i-x_j))

    (F_i(x)=prod_{j=1}^{i-1}(x-x_j)),则答案为 (prod F_i(x_i))。可以发现多点求值在递归时可以顺便算出 (F_i(x))


    快速插值

    从拉格朗日插值入手优化:(F(x)=sum_{i=1}^{n} y_i imesfrac{prod_{j=1,j ot=i}^{n}(x-x_j)}{prod_{j=1,j ot=i}^{m}(x_i-x_j)})

    首先考虑求出 (k_i=prod_{j=1,j ot=i}^{n}(x_i-x_j) = lim_{x o x_i}frac{prod_{j=1}^{n}(x_i-x_j)}{x-x_i})。记 (G(x)=prod_{j=1}^{n}(x-x_j)),洛必达一下得 (k_i=G'(x_i)),多点求值即可。

    考虑 (F(x)=sum_{i=1}^{n}frac{y_i}{v_i}prod_{j=1,j ot = i}^{n}(x-x_j)),可以考虑类 cdq 分治的方法求,即 (F(x)=F_L(x)P_R(x)+F_R(x)P_L(x))(这里的 (P) 和上面的多点求值是同一定义)。


    多点求值(新)

    转置原理是个啥啊,算了不管了。

    “然而 $E在此基础上加了很多优化,所以他可以 5e5 多点求值。”——《$E为什么可以5e5多点求值(详细揭秘)

    attention:以下的记法并不严谨,仅作为个人学习的辅助记法。

    一般的卷积定义为 (f_{i+j}=sum g_ih_j),用形式幂级数记为 (F(x) = G(x)cdot H(x))

    我们定义另一种 “卷积“ (f_{i-j}=sum g_ih_j),用形式幂级数记为 (F(x)=G(x) imes H(x))(注意它其实并不交换也不结合,所以不能算真正的卷积)。

    那么有 (F(a) = [x^0](F(x) imesfrac{1}{1-ax})),将求值问题转化成了 “卷积” 问题。

    注意到 (F(x) imes(G(x)cdot H(x)) = (F(x) imes G(x)) imes H(x))(根据定义,这是显然的)。

    一样考虑分治,尝试根据 (F(x) imes(prod_{i=l}^{r}frac{1}{1-a_ix})) 求出 (F(x) imes(prod_{i=l}^{mid}frac{1}{1-a_ix}))(F(x) imes(prod_{i=mid+1}^{r}frac{1}{1-a_ix})),根据上面那条性质算即可。

    由于我们只需要求 (x^0) 的系数,所以分治时可以只保留有用的项,因此时间复杂度 (O(nlog ^2 n))(然而这个方法只需要一次求逆得到 (prod_{i=1}^{n}frac{1}{1-a_ix}))。

    其他应用可以看今年WC的员交课件?


    多项式复合

    目前最优复杂度可以做 (O((nlog n)^{1.5})),然而我不会,所以咕掉了。

    复合即是给定 (F(x)=sum f_i x^i, G(x)=sum g_i x^i),求 (sum f_i G^i(x))

    有一个比较好的替代复杂度为 (O(n^2+nsqrt{n}log n))

    类似 BSGS,我们处理出 (G^{i imessqrt{n}}(x))(G^i(x)) 的 dft,然后 (O(n^2)) 暴力乘并卷回去。

    复合逆也可以结合拉格朗日反演公式 + 分块做到 (O(n^2 + nsqrt{n}log n))

  • 相关阅读:
    【Win10开发】相对布局——RelativePanel控件
    【Win10开发】关于AutoSuggestBox
    【Win10开发】自定义标题栏
    线上服务器CPU100%排查
    Rest接口单元测试
    hibernate validator参数校验&自定义校验注解
    JsonView视图
    跨域(SpringBoot)
    Mybatis的分支选择和In循环
    CentOS6.5使用yum安装mysql
  • 原文地址:https://www.cnblogs.com/Tiw-Air-OAO/p/13414531.html
Copyright © 2011-2022 走看看