多项式求逆元详解+模板 【洛谷P4238】多项式求逆

摘要:
概述多项式的逆是一个非常重要的知识点。许多多项式运算需要使用此算法,包括多项式模、除法、开尾、ln、exp和快速幂。多项式的逆函数是一个$a$的多项式,其阶数为$deg_a$,如果有一个$B$多项式,使其满足$deg_B≤deg_a$和$AimesBequiv1$,则$B$是$a$在模块$x^n$意义上的乘法逆函数。其中$a_0$、$b_0$表示多项式$a$和多项式$b$的常数项。Logo中存在一个称为多项式逆的问题(单击此处)。你可以先这样做。

概述

多项式求逆元是一个非常重要的知识点,许多多项式操作都需要用到该算法,包括多项式取模,除法,开跟,求ln,求exp,快速幂。用快速傅里叶变换和倍增法可以在$O(n log n)$的时间复杂度下求出一个$n$次多项式的逆元。

 

前置技能

快速数论变换(NTT),求一个数$x$在模$p$意义下的乘法逆元。

 

多项式的逆元

给定一个多项式$A(x)$,其次数为$deg_A$,若存在一个多项式$B(x)$,使其满足$deg_B≤deg_A$,且$A(x) imes B(x) equiv 1 (mod x^n)$,则$B(x)$即为$A(x)$在模$x^n$意义下的的乘法逆元。

 

求多项式的逆元

我们不妨假设,$n=2^k,k∈N$。

若$n=1$,则$A(x) imes B(x) equiv a_0 imes b_0 equiv 1 (mod x^1)$。其中$a_0$,$b_0$表示多项式$A$和多项式$B$的常数项。

若需要求出$b_0$,直接用费马小定理求出$a_0$的乘法逆元即可。

当$n>1$时:

我们假设在模$x^{frac{n}{2}}$的意义下$A(x)$的逆元$B'(x)$我们已经求得。

依据定义,则有

$A(x)B'(x)equiv 1 (mod x^{frac{n}{2}})$          $(1)$

对$(1)$式进行移项得

$A(x)B'(x)-1equiv 0 (mod x^{frac{n}{2}})$          $(2)$

然后对$(2)$式等号两边平方,得

$A^2(x)B'^2(x)-2A(x)B'(x)+1equiv 0(mod x^{n})$          $(3)$

将常数项移动到等式右侧,得

$A^2(x)B'^2(x)-2A(x)B'(x)equiv -1(mod x^{n})$          $(4)$

将等式两边去相反数,得

$2A(x)B'(x)-A^2(x)B'^2(x)equiv 1(mod x^{n})$          $(5)$

下面考虑回我们需要求的多项式$B(x)$,依据定义,其满足

$A(x)B(x)equiv 1(mod x^{n})          $(6)$

将$(5)-(6)$并移项,得

$A(x)B(x)equiv 2A(x)B'(x)-A^2(x)B'^2(x)(mod x^{n})$          $(7)$

等式两边约去$A(x)$,得

$B(x)equiv 2B'(x)-A(x)B'^2(x)(mod x^{n})$          $(8)$

 

 

显然,我们可以用上述式子求出$B(x)$。

这一步的计算我们可以使用$NTT$,时间复杂度为$O(n log n)$。

我们可以通过递归的方法,求解出$B(x)$。

时间复杂度$T(n)=T(dfrac{n}{2})+O(n log n)=O(n log n)$。

 

洛谷上有一道题目就叫做多项式求逆元(点这里),可以先做下那一题。

模板如下:

 

 1 #include<bits/stdc++.h>
 2 #define M (1<<19)
 3 #define L long long
 4 #define MOD 998244353
 5 #define G 3
 6 using namespace std;
 7 
 8 L pow_mod(L x,L k){
 9     L ans=1;
10     while(k){
11         if(k&1) ans=ans*x%MOD;
12         x=x*x%MOD; k>>=1;
13     }
14     return ans;
15 }
16 
17 void change(L a[],int n){
18     for(int i=0,j=0;i<n-1;i++){
19         if(i<j) swap(a[i],a[j]);
20         int k=n>>1;
21         while(j>=k) j-=k,k>>=1;
22         j+=k;
23     }
24 }
25 void NTT(L a[],int n,int on){
26     change(a,n);
27     for(int h=2;h<=n;h<<=1){
28         L wn=pow_mod(G,(MOD-1)/h);
29         for(int j=0;j<n;j+=h){
30             L w=1;
31             for(int k=j;k<j+(h>>1);k++){
32                 L u=a[k],t=w*a[k+(h>>1)]%MOD;
33                 a[k]=(u+t)%MOD;
34                 a[k+(h>>1)]=(u-t+MOD)%MOD;
35                 w=w*wn%MOD;
36             }
37         }
38     }
39     if(on==-1){
40         L inv=pow_mod(n,MOD-2);
41         for(int i=0;i<n;i++) a[i]=a[i]*inv%MOD;
42         reverse(a+1,a+n);
43     }
44 }
45 
46 void getinv(L a[],L b[],int n){
47     if(n==1){b[0]=pow_mod(a[0],MOD-2); return;}
48     static L c[M],d[M];
49     memset(c,0,n<<4); memset(d,0,n<<4);
50     getinv(a,c,n>>1);
51     for(int i=0;i<n;i++) d[i]=a[i];
52     NTT(d,n<<1,1); NTT(c,n<<1,1);
53     for(int i=0;i<(n<<1);i++) b[i]=(2*c[i]-d[i]*c[i]%MOD*c[i]%MOD+MOD)%MOD;
54     NTT(b,n<<1,-1);
55     for(int i=0;i<n;i++) b[n+i]=0;
56 }
57 L a[M]={0},b[M]={0};
58 int main(){
59     int n,N; scanf("%d",&n);
60     for(int i=0;i<=n;i++) scanf("%lld",a+i);
61     for(N=1;N<=n;N<<=1);
62     getinv(a,b,N);
63     for(int i=0;i<=n;i++) printf("%lld ",b[i]);
64 }

免责声明:文章转载自《多项式求逆元详解+模板 【洛谷P4238】多项式求逆》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Apache 分割日志IOS ——OC——NSMutableString的用法大全(个人总结)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

随便看看

svn常见问题汇总

要添加到版本库,必须更新工作副本中的文件。5.更新时,系统会提示您文件冲突,将工作副本中的文件与服务器中的文件进行比较“当版本管理系统更改计算机上的工作副本时”,它会尝试将您的意图写入计算机上的日志文件,因此日志文件记录可能与您的上次工作状态不一致。Subversion客户端将在提交内容之前在本地工作副本中写入日志。首先删除隐藏文件夹中tmp下的临时文件。服...

目录扫描工具DirBuster

DirBuster用于检测web服务器上的目录和隐藏文件。因此,必须在运行之前安装Java环境。在TargetURL下输入要检测的网站的地址。请注意,地址应与协议一起添加。一种是自动选择。它将决定是使用head方法还是get方法。number of Thread是所选扫描线程的数量,selectscanning type是所选的扫描类型。Listbasedb...

支付宝支付api

使用:alipayDemo来配置支付宝支付接口1拿到商户号,回调地址,支付宝公钥,我的私钥---生成一个对象#给支付宝发请求,信息要用支付宝公钥加密#支付宝给我响应信息,信息会用商户的公钥加密,回来之后再拿用户私钥解密2对象.direct_pay传支付金额,支付商品描述,支付订单号---返回个加密的串3拿到加密的串拼到get请求参数部分pay_url="ht...

git使用说明

初次使用请参考百度,google,博客园。1修改文件并提交到github[luwenwei@dev01v~/git/helww/labs]$vimREADME[luwenwei@dev01v~/git/helww/labs]$gitdiffdiff--gita/READMEb/READMEindex39d8172..464c83f100644---a/REA...

java实现word转pdf文件(高效不失真)

importjava.io.File;importjava.io.FileOutputStream;importjava.io.InputStream;importorg.aspectj.weaver.ast.Test;importcom.aspose.words.Document;importcom.aspose.words.License;importc...

avue 常用修改

1.搜索栅栏调整colum中对象的属性:searchSpan:4,column:[{label:"模型名称",prop:"name",search:true,searchSpan:4,},2.搜索框字段位置长度column:[{label:"流程标题23423432",searchLabelWidth:200,3.编辑页面,字段lable宽度设置labelW...