zoukankan      html  css  js  c++  java
  • 省选复习

    多项式全家桶

    听起来很吓人的名字(在我学之前),慢慢知识积累上去,你会发现它就是一堆数学推导。

    不断更新中...

    当前进度:多项式exp / 常系数齐次线性递推

    基础知识

    微积分

    (暂时)并不需要太高的水平,最基本的会即可。

    基础求导:

    (C'=0)

    ((x^n)'=nx^{n-1})

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

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

    ((Cf(x))'=Cf'(x))

    ((fpm g)'=f'pm g')

    ((fg)'=f'g+fg')

    ((dfrac{f}{g})'=dfrac{f'g-fg'}{g^2})

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

    基础积分:

    把上面这些反过来

    FFT/NTT

    这还要讲?

    泰勒展开

    现在已知一个函数 (f(x))。要用一个多项式函数 (g(x)) 逼近它

    考虑先选取一个起点 (x_0),以这个位置为参考 (一般这个位置要好算一些,或者有可以利用的数值)

    然后我们的主体思路是,让 (f,g)(x_0) 处的值,一阶导,二阶导,三阶导...都相同。

    首先我们让 (f,g)(x_0) 处相同。那 (g) 先加上一项 (f(x_0)) 的常数。

    然后我们让它的一阶导相同,那我们要给它来点多项式了。但是注意我们不能改变取值,于是我们只能加上 (x-x_0) 的若干倍。

    (g_k) 表示一个函数,它在 (x_0) 处的 (k) 阶导和 (f) 相同。

    考虑 (g_1)

    (x=x_0) 时,(g_1'(x)=f'(x_0))

    同时积分,(g_1(x)=xf'(x_0)+C)

    为了凑 (x-x_0),我们令 (g_1(x)=(x-x_0) f'(x_0))

    考虑 (g_2)

    同时积分两次

    (g_2(x_0)=dfrac{1}{2} f''(x_0)x_0^2 + C(x))(C(x)) 是任意至多一次的多项式。

    同理,我们令 (g_2(x)=dfrac{1}{2}f''(x_0) (x-x_0)^2)

    这里出现了分数,容易发现这个分数是积分的时候积出来的,积了多少次,就会有多少个,所以是一个阶乘

    所以 (g_k(x)=dfrac{f^{(k)}(x_0) (x-x_0)^k}{k!})

    然后把所有的 (g_k) 和常数项加起来,得到:

    [g(x)=sumlimits_{i=0}^{infin} dfrac{f^{(i)}(x_0)(x-x_0)^i}{i!} ]

    牛顿迭代

    首先,我们对一个多项式 (mod {x^n}),意思就是取前 (n-1) 项,这个东西想想就明白了。

    另外,因为同余 (equiv) 很不好打,后面 (=) 也表示同余 —— 这个写法很不好,但看到后面有 (pmod{...}) 便可知这个 (=) 表示同余。

    回到正题。现在我们要解一个多项式方程 (E(f)=0),其中 (f) 是一个未知多项式,我们要找出来它。

    而实际问题中我们一般只需要 (f) 的前 (k) 项,也就是 (mod x^k) 的解。

    假设我们知道了 (E(f_0)=0 pmod{x^n}),要找一个 (E(f)=0 pmod{x^{2n}})

    假设能这么求,那么求 (log) 次,就可以求出 (mod x^k) 的解了。

    我们在 (f_0) 处展开 (E),并求 (f) 位置的值 (没错,展开结果是一个多项式套多项式,会有若干个 (f) 的若干次方)

    (E(f)=E(f_0)+E'(f_0)(f-f_0)+dfrac{E''(f_0)(f-f_0)^2}{2!}+...)

    我们强制令 (f=f_0 pmod{x^n}),容易证明,如果 (E) 有解,那这样一定能找到一个解。

    证:

    假设 (E(g)=0 pmod{x^{m}}),其中 (m) 是一个足够大的数 —— 比我们要用的所有 (n)

    考虑 (f=gmod x^n)

    (g) 处展开 (E),代入 (f) 求值

    (E(f)=E(g)+E'(g)(f-g)+...)

    由于 (f=g pmod{x^n}),所以 (f-g=0 pmod{x^n}) ,于是 (E(f)=E(g)=0 pmod{x^n})

    也就是我们要找的 (mod x^n) 的解,当然,(m) 再大一点,容易证明,把 (n) 换成 (2n) ,或者是我们想要的 (k) ,都是成立的,都能找到解

    然后注意到 ((f-f_0)^2=0pmod{x^{2n}}),后面的次数更大,都包含这个因子 —— 所以从 (2) 开始我们全都不用要了。

    然后 (E(f)=E(f_0)+E'(f_0)(f-f_0))

    移项并整理:

    [f=f_0-dfrac{E(f_0)}{E'(f_0)} ]

    然后每次这么求一遍就可以了。关于如何算除法,后面再说。

    牛顿迭代的代码实现

    假设我们现在已经知道了多项式乘法,这里直接假设封装了 operator (实际上我并没有这么干,因为我试过一次,很慢,也不知如何优化)

    相当于半个伪代码和C++

    void solve(euqation E,poly& g,int n) 
    // E 是那个方程
    // 实际代码实现中, 通常是传一个方程的参数进来, 然后通过推式子手动求方程的值和求导之类的
    // 另外, 一般这里的g是传数组进来, 就不用&了
    {
    	int len,lim;
    	poly g=trival(); // 先瞪出来一个trival的边界值
    	for(len=1;len<=(n<<1);len<<=1)
    	{
    		lim=len<<1; // 这个是 FFT/NTT 要用的
    
    		E_=deri(E); // 求导
    		// 实际上我们是需要手动求导的, 而且不会写成这样, 这里仅供示意
    		g=g-E(g)*inv(E_(g)); // inv: 求逆, 后面讲, 乘以一个多项式的逆相当于除
            // 顺便, 一般这里求 E 啥的还要再来一堆辅助数组
    	}
    	return g;
    }
    

    别问我为啥要贴这个,我初学的时候尝试自己想怎么写,但是一直不知道lim和len咋搞

    如果您自己想出来了,恭喜你,把我吊打了

    多项式正题

    多项式乘法

    FFT/NTT 直接上

    多项式求逆

    已知 (f),求 (g) 使 (fg=1 pmod{x^k})

    (g=f^{-1})。由于逆元的对称性,(f=g^{-1})

    牛顿迭代需要用除法,而多项式求逆就是用来解决除法的,所以牛顿迭代比多项式求逆高 —— 换句话说我们没法用牛顿迭代算多项式求逆。这就好比你没法生下来你妈,因为你是你妈生的 超 级 加 辈

    但是这个思路值得借鉴。假设有(g_0) 使 (fg_0=1 pmod{x^n}),求 (g) 使 (fg=1 pmod{x^{2n}})。还是令前 (n) 项相同,然后考虑 ((g-g_0)^2),显然它 (=0 pmod{x^{2n}})

    展开它,变成

    (g^2-2gg_0+g_0^2=0pmod{x^{2n}})

    同时乘以 (f)

    (fg^2-2fgg_0+fg_0^2=0pmod{x^{2n}})

    我们设 (fg=1 pmod{x^{2n}}),所以可以代入一下变成

    (g-2g_0+fg_0^2=0pmod{x^{2n}})

    移项得:

    [g=2g_0-fg_0^2 ]

    然后迭代即可。上面提到,除相当于乘以逆元。于是就可以算除法了。

    多项式对数函数(ln)

    要求 (g(x)=ln(f(x)) pmod{x^k})

    (x) 为主元来导,(g'(x)=dfrac{1}{f(x)}f'(x))

    然后积回去:

    [g(x)=int dfrac{f'(x)}{f(x)} ]

    (为啥打中间是因为这样的积分好看,打在行间就是 (int)

    多项式指数函数(exp)

    非常好听的名字:exp。它也有很完美的性质,一切都是 (e) 这个神秘数字的魅力。

    先回到正题。要求:(g=exp(f)=e^f pmod{x^n})

    相当于 (ln(g)-f=0)

    (E(g)=ln(g)-f)。易得 (E'(g)=dfrac{1}{g})(这里设 (g) 为主元,然后 (f) 就是常数,也不用链式法则了)

    换句话说求的是 (dfrac{dE(g)}{dg})

    (g=g_0-dfrac{E(g_0)}{E'(g_0)}=g_0-dfrac{ln(g_0)-f}{dfrac{1}{g_0}})

    整理一下就是

    [g=g_0(1-ln(g_0)+f) ]

    然后它的完美性质是甚么?

    假设我们知道一个东西 (A) ,它的数量的的生成函数是 (F)

    然后有另一个东西 (B),它的数量的生成函数是 (G)

    然后 (B) 是由若干个 (A) 无序拼起来的。

    这样的例子很多,比如说置换是由循环置换拼起来的,任意图是由若干连通图拼起来的,森林是由树拼起来的...

    然后 (G=exp(F))

    为什么呢?枚举 (A) 用了多少个,假设是 (i) 个。然后它们的大小的和要等于 (n),也就是一个多元卷积的形式。又因为是无序的,所以要除以 (i!)

    于是有 (G=sumlimits_{i=1}^{infin}dfrac{F^i}{i!})

    然后这玩意就是 (exp(x))(x_0=0) 处的展开 (容易验证)。于是 (G=exp(F))

    当然它还有更多完美的性质,此处略

    不太有用的东西

    指多项式开根/三角函数

    题目里没见到过,只有板子里有。 也可能是我too young too simple

    反正牛迭随便推一下就行了

    多项式快速幂

    先开 (ln),然后乘以 (k) (我们要的幂),然后再 (e) 回来。一个 (log),比倍增快速幂快。

    多项式带余除法

    给定 (F,G),次数分别是 (n,m)

    (Q,R) 使得 (F=QG+R),其中 (R) 的次数必须小于 (m) —— 容易证明存在唯一的 (G,R)

    (其中我们称 (Q) 为商,(R) 为余数)

    考虑模 (x^n) 这个操作,它可以去掉多项式从 (n) 开始的更高的次数,只保留 ([0,n-1]) 次。换句话说,它体现在数组上去掉了一个 后缀

    然后现在比较不好处理的就是这个 (R) 。我们希望用一个类似取模的东西,去掉一个 前缀,直接多项式乘法逆就可以求出 (Q) 了。

    那这不是很好办么,前缀反过来就是后缀了。但是请注意,(R) 的次数很小,反过来的时候注意补项。

    于是得到了问题的解决办法:

    • (F,G) 做一遍 (reverse),设得到了 (F_r,G_r)。然后 (Q=F_r imes (G_r)^{-1})
    • (R=F-QG),直接乘然后减就完了

    常系数齐次线性递推

    单独出来写吧,有点长

    ko↑ko↓

    多项式多点求值 / 快速插值

    咕咕咕~

    多项式复合 / 多项式复合逆

    咕咕咕~

    普通多项式和下降幂多项式的转化

    斯特林数瞎搞一番就行了

    本质上也是咕咕咕

    鸽 王 争 霸 赛

  • 相关阅读:
    hyper-v启动虚拟机时提示“The application encountered an error while attempting to change the state of the machine ‘虚拟机名称'”如何处理?
    ubuntu下如何开机自动执行自定义脚本?
    centos下如何开放某个端口?
    linux都有哪些运行级别?
    linux内核在挂载ramdisk的过程中报错"RAMDISK: incomplete write (10739 != 32768)"如何处理?
    linux内核挂载根文件系统时报错”VFS: Cannot open root device "ram0" or unknown-block(0,0): error -6“如何处理?
    c代码审查软件
    项目管理术语表
    项目管理常用缩写
    MYSQL的读写分离主从延时问题
  • 原文地址:https://www.cnblogs.com/LightningUZ/p/14322096.html
Copyright © 2011-2022 走看看