Loading [MathJax]/extensions/TeX/mathchoice.js

多项式求逆

概述

对于多项式 f(x)。

求逆:若存在 g(x) 满足 f(x)g(x) ≡ 1 (mod xn), 则称 g(x) 为 f(x) 在模 xn 意义下的逆元, 记作 f-1(x)。

对数:可以将其对数函数看做其与麦克劳林级数的复合:

ln(1f(x))=+i=1fi(x)iln(1+f(x))=+i=1(1)i1fi(x)i

指数:

ef(x)=+i=0fi(x)i!


求逆

首先, 对于 b>a, A(x) 在模 xb 下的逆元, 同时也是 A(x) 在模 xa 下的逆元。

于是可以求出模 x2k 下的逆元, 以下介绍倍增法。

首先, A(x) ≡ c (mod x), c 是一个常数, 则 A-1(x) (mod x) 就是 c-1

然后, 假设:

A(x)B'(x) \equiv 1 \mod x^{n/2} \\ A(x)B(x) \equiv 1 \mod x^n

由于显然有 A(x)B(x) \equiv 1 \mod x^{n/2}

于是有:A(x)(B(x)-B'(x)) \equiv 0 \mod x^{n/2}, 即 B(x)-B'(x) \equiv 0 \mod x^{n/2}

然后两边平方:B(x)^2 + B'(x)^2 - 2B(x)B'(x) \equiv 0 \mod x^n

模数也可以一起平方的原因, 详见 miskoo的 blog

然后乘上 A(x) 并移项:B(x) \equiv 2B'(x) - A(x)B'(x)^2 \mod x^n

这就是倍增的过程了。

时间复杂度是 T(n) = T(n/2) + O(n\log n) = O(n\log n), 注意 T(n/2) 前面没有乘以二, 所以总复杂度不是 O(n\log^2 n)


实际代码实现的时候, 其实模数的次幂可以是任意正整数(证明同 miskoo 的证明), 只需要求出模 x^{\lceil n/2\rceil} 下的逆, 就可以用上述方法求出模 x^n 下的逆。

// 交板子过了, 保证正确
void poly_inv(int deg, int *a, int *b) {
	if(deg == 1) { b[0] = ksm(a[0], mo-2); return; }
	poly_inv((deg + 1) >> 1, a, b);
	int len = 1; while(len < (deg << 1)) len = len << 1;
	for(int i=0; i<deg; ++i) c[i] = a[i];
	for(int i=deg; i<len; ++i) c[i] = 0;
	
	for(int i=1; i<len; ++i) rv[i] = (rv[i>>1]>>1) | (i&1?len>>1:0);
	NTT(c, len, 1), NTT(b, len, 1);
	for(int i=0; i<len; ++i) b[i] = (LL)b[i] * (2ll - (LL)c[i] * b[i] % mo) % mo;
	NTT(b, len, -1);
	
	for(int i=deg; i<len; ++i) b[i] = 0;
}
posted @   xwmwr  阅读(262)  评论(0编辑  收藏  举报
编辑推荐:
· 智能桌面机器人:用.NET IoT库控制舵机并多方法播放表情
· Linux glibc自带哈希表的用例及性能测试
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
阅读排行:
· 手把手教你在本地部署DeepSeek R1,搭建web-ui ,建议收藏!
· 新年开篇:在本地部署DeepSeek大模型实现联网增强的AI应用
· Janus Pro:DeepSeek 开源革新,多模态 AI 的未来
· 互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(三):用.NET IoT库
· 【非技术】说说2024年我都干了些啥
点击右上角即可分享
微信分享提示