zoukankan      html  css  js  c++  java
  • 多项式的各种运算总结(持续更新)

    多项式的各种运算总结(持续更新)

    标签: 多项式开方 多项式求逆


    多项式

    多项式是个啥呢?
    我们通常说的都是一元的多项式,所以一个多项式可以写成形如:
    (a_ 0+a_ 1x+a_ 2x^2+a_ 3x^3......)的式子
    注意到,真正有用的是数列({a_i})
    但是一旦我们要涉及到什么运算,就会发现对于({a_i})的某些运算不是特别方便。
    所以我们定义生成函数(A(x)=sum_{i=0}^{infty}a _ix^i)(A(x))就称为数列({a _i})的生成函数。
    通过生成函数,我们可以重新定义对于数列的一系列运算。

    相等

    对于数列来说,相等的条件是数列的每一项都相等。
    但是对于生成函数来讲,对于任意(xin C)都有(A(x)=B(x)),那么有多项式(A(x)=B(x))

    加法

    对于数列来说,加法就是数列的每一项都做加法。
    但是对于生成函数来讲,对于任意(xin C)都有(C(x)=A(x)+B(x)),那么有多项式(C(x)=A(x)+B(x))

    讲了这么多,是不是感觉很没用,too young too simple啊,接下来看点有用的。

    乘法

    假如数列({c_i})是数列({a _i},{b _i})相乘的结果,
    那么有(c_i=sum_{j=0}^ia _jb_{i-j})
    注意到直接计算的复杂度是(O(n^2))的。
    这时候,就需要用到生成函数了。
    显然,对于任意(x in C),都有(C(x)=A(x)B(x)),那么多项式(C(x)=A(x)B(x))
    借用方程的思想,如果我们知道了这个多项式n+1个点的值,那么就可以确定这个多项式的前n+1项。(假设其他项都为0)
    所以现在的问题是,怎么快速的计算这n+1个点的值。
    由于点是我们随便取得,我们可以通过取一些特殊的点来达到这个目的。
    不妨取1的n次负根的各个次幂,设(w_ n)表示1的n次复根,我们分别取(w_ n^0,w_ n^1,......w_ n^{n-1})
    对于这些点来说,有一些奇怪的性质。

    1. (w_ {2n}^{2k}=w_ n^k)
    2. (w_ {2n}^{k}=-w_ {2n}^{k+n})

    这有什么用呢,
    假如要求一个多项式(A(x)=sum_{i=0}^{2n-1}a _ix^i)(w _{2n}^k(kin[0,2n)))代入的结果
    我们可以利用分治的思想,先求出(B(x)=sum_{i=0}^{n-1}a _{2i}x^i,C(x)=sum _{i=0}^{n-1}a _{2i+1}x^i)(w _{n}^k(kin[0,n)))代入的结果。
    接下来,对于任意一个(A(w _{2n}^k)),都能表示成(B,C)两个多项式的和。

    我们只需要对k讨论即可。
    假如(k < n),那么(A(w _{2n}^k))=(B(w _n^k)+w _{2n}^kC(w _n^k))
    假如(k >= n),那么(A(w _{2n}^k))=(B(w _n^{k-n})-w _{2n}^{k-n}C(w _n^{k-n}))

    这样,复杂度(T(n)=O(n)+2T(n/2))
    最终复杂度为(O(nlogn))

    我们现在已经将多项式转化成了点值,如果想将点值重新转化成多项式,只需要再做一次逆矩阵的乘法即可。
    实现的时候还需要注意,因为分治严格的分成了两份,所以一开始先要把n变为2的幂,然后才能做分治。

    除了整个复数域都可以,模意义下也可以进行多项式的乘法。
    可以注意到,原根有着与上面一样的性质。
    模意义下,显然有(x^{p-1 over 2}=-1)(x为p的原根,p为质数)
    于是在模意义下也可以进行多项式乘法。

    求逆

    对多项式而言,两个多项式相乘等于单位多项式,那么这两个多项式互逆。
    显然,单位多项式的条件是任何多项式乘以单位多项式都为原来的多项式。
    不难发现这样的多项式是(F(x)=1)
    写成数学符号:若(A(x)B(x)=1),则(A,B)两个多项式互逆。
    当然,一般情况下几乎都是在模意义下进行,而且只关注前n项的值。
    和乘法类似,求逆也需要用到分治的方法。
    (A(x)B(x)=C(x) [n])代表(A(x)与B(x)的乘积在前n项的结果与多项式C(x)的前n项相同)

    假如有(A(x)C(x)=1 [{n over 2}])
    我们需要知道(B(x)C(x)=1 [n])
    相减得((B(x)-A(x))C(x)=0 [n over 2])
    显然(C(x))不等于0.
    所以(B(x)-A(x)=0 [{n over 2}])
    但是我们需要求的是前n项的,所以我们可以对上面这个式子平方。
    如果一个多项式前({n over 2})项都是0,那么平方之后前(n)项应该都是0.
    ((B(x)-A(x))^2=0[n])
    (A(x)^2-2A(x)B(x)+B(x)^2=0 [n])
    移项,得(B(x)^2=2A(x)B(x)-A(x)^2)
    (B(x)=2A(x)-{A(x)^2 over B(x)})
    又有$B(x)C(x)=1 [n] ( 分母分子同时乘上)C(x)(, 得)B(x)=2A(x)-A(x)^2C(x)$
    当n=1时,显然可以直接求逆元。

    复杂度(T(n)=T(n/2)+O(nlogn))

    开方

    即求(B(x)^2=C(x) [n])
    借用刚才的思路,我们先求出(A(x)^2=C(x) [{n over 2}])
    (B(x)^2-A(x)^2=0 [{n over 2}])
    ((B(x)^2-A(x)^2)^2=0 [n])
    那么 (A(x)^4-2A(x)^2B(x)^2+B(x)^4 =0 [n])
    (B(x)^2={A(x)^4+B(x)^4 over 2A(x)^2}[n])
    (2B(x)^2={(A(x)^2+B(x)^2)^2 over 2A(x)^2}[n])
    (B(x)^2=({A(x)^2+B(x)^2 over 2A(x)})^2[n])
    (B(x)^2=({A(x)^2+C(x) over 2A(x)})^2[n])
    那么括号里面的即为所求。
    当其只有一项的时候,只需要在模意义下做二次剩余即可。

    (未完待续)

  • 相关阅读:
    小乖乖的Linux历险记
    走近虚拟机与Linux
    Navicat for MySQL数据库管理工具安装和破解
    Spring + Struts + Hibernate 简单封装通用接口
    Java 学习路线图
    Java Mail 发送带有附件的邮件
    Java POI 读取Excel数据转换为XML格式
    Spring + Struts + Hibernate + Bootstrap-table 实现分页和增删改查
    Java 基础知识
    SSH三大框架知识点
  • 原文地址:https://www.cnblogs.com/gzy-cjoier/p/8451245.html
Copyright © 2011-2022 走看看