多项式全家桶

开头Orz yww,Orz xfz,Orz dtz,Orz lyy

一些定义

一个关于$x$的多项式$A(x)$可以表示为如下形式和:

$A(x)=\sum\limits_{i=0}^{n-1}a_{i}x^{i}$

其中$a_0,a_1,a_2......a_{n-1}$称为多项式$A(x)$的系数,如果$A(x)$最高次数的一个非零项系数为$a_k$,则称其次数为$k$。任意一个严格大于$k$的整数都可以作为这个多项式的次数界,即对于一个次数界为$n$的多项式,他的次数可以是$[0,n-1]$中的任意一个整数。

多项式加减法

多项式乘法

直接FFT or NTT

代码:

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<cmath>
 5 #define pw(n) (1<<n)
 6 using namespace std;
 7 const double pi=acos(-1);
 8 struct complex{
 9     double a,b;
10     complex(double _a=0,double _b=0){
11         a=_a;
12         b=_b;
13     }
14     friend complex operator +(complex x,complex y){return complex(x.a+y.a,x.b+y.b);}
15     friend complex operator -(complex x,complex y){return complex(x.a-y.a,x.b-y.b);}
16     friend complex operator *(complex x,complex y){return complex(x.a*y.a-x.b*y.b,x.a*y.b+x.b*y.a);}
17     friend complex operator *(complex x,double y){return complex(x.a*y,x.b*y);}
18     friend complex operator /(complex x,double y){return complex(x.a/y,x.b/y);}
19 }a[100001],b[100001];
20 int n,m,bit,bitnum=0,rev[pw(20)];
21 void getrev(int l){//Reverse
22     for(int i=0;i<pw(l);i++){
23         rev[i]=(rev[i>>1]>>1)|((i&1)<<(l-1));
24     }
25 }
26 void FFT(complex *s,int op){
27     for(int i=0;i<bit;i++)if(i<rev[i])swap(s[i],s[rev[i]]);
28     for(int i=1;i<bit;i<<=1){
29         complex w(cos(pi/i),op*sin(pi/i));
30         for(int p=i<<1,j=0;j<bit;j+=p){//Butterfly
31             complex wk(1,0);
32             for(int k=j;k<i+j;k++,wk=wk*w){
33                 complex x=s[k],y=wk*s[k+i];
34                 s[k]=x+y;
35                 s[k+i]=x-y;
36             }
37         }
38     }
39     if(op==-1){
40         for(int i=0;i<=bit;i++){
41             s[i]=s[i]/(double)bit;
42         }
43     }
44 }
45 int main(){
46     scanf("%d%d",&n,&m);
47     for(int i=0;i<=n;i++)scanf("%lf",&a[i].a);
48     for(int i=0;i<=m;i++)scanf("%lf",&b[i].a);
49     m+=n;
50     for(bit=1;bit<=m;bit<<=1)bitnum++;
51     getrev(bitnum);
52     FFT(a,1);
53     FFT(b,1);
54     for(int i=0;i<=bit;i++)a[i]=a[i]*b[i];
55     FFT(a,-1);
56     for(int i=0;i<=m;i++)printf("%d ",(int)(a[i].a+0.5));
57     return 0;
58 }

时间复杂度:$O(nlogn)$

多项式除法(取模)

多项式求逆

如果存在多项式$B(x)$使得:

$A(x)B(x)≡1(mod  x^n)$

则$B(x)$称为$A(x)$在模$x^n$意义下的乘法逆元;

一个多项式存在乘法逆元的充要条件是他的常数项存在乘法逆元(不会证)

假设已经求出了$B'(x)$满足:

$A(x)B'(x)≡1(mod  x^{\lceil \frac{n}{2}\rceil})$

$A(x)B'(x)-1≡0(mod  x^{\lceil \frac{n}{2}\rceil})$
$(A(x)B'(x)-1)^2≡0(mod x^n)$

$A^2(x)B'^2(x)-2A(x)B'(x)+1≡0(mod  x^n)$
$2A(x)B'(x)-A^2(x)B'^2(x)≡1(mod  x^n)$

将此式减去$A(x)B(x)≡1(mod x^n)$,可得

$2A(x)B'(x)-A^2(x)B'^2(x)A(x)B(x)≡0(mod  x^n)$

约去$A(x)$,得

$2B'(x)-A(x)B'^2(x)-B(x)≡0(mod  x^n)$
$2B'(x)-A(x)B'^2(x)≡B(x) (mod  x^n)$

 于是就可以每次算出$2B'(x)-A(x)B'^2(x)$然后赋值给$B(x)$进行下一次迭代,因此时间复杂度为$T(n)=T(\frac{n}{2})+O(nlogn)=O(nlogn)$,看着像是两个$log$的,实际上只有一个,这里提供一个lyy的证明:

设$n=2^k$

则$T(n)=T(\frac{n}{2})+O(nlogn)=\sum\limits_{i=0}^{k}\frac{n}{2^i}logn=nlogn$

dtz:轻松证明

代码:咕咕咕

多项式开根

多项式求幂

多项式对数函数

多项式指数函数

多项式导数&多项式积分

从yww那里盗了两个式子,看的云里雾里的,先留个坑,等看懂了再说

设$A(x)=\sum_{i\ge 0}$,则$A(x)$的形式导数为:

$A'(x)=\sum\limits_{i\ge 1}ia_{i}x^{i-1}$

$A$同上,则:

$\int\limits A(x)=\sum\limits_{i\ge 1}\frac{a_{i-1}}{i}x^i$

猜你喜欢

转载自www.cnblogs.com/dcdcbigbig/p/9359329.html
今日推荐