多项式操作

先是一些操作。
临时数组还是开static省的乱掉。
参考资料:
https://blog.csdn.net/semiwaker/article/details/73251486
https://www.cnblogs.com/zwfymqz/p/9132189.html#_label10_4


NTT

void NTT(int n,ll a[],int f){
    for(int i=0;i<n;i++) if(i<r[i]) swap(a[i],a[r[i]]);
    for(int i=1;i<n;i<<=1){
        ll wn=ksm(3,f==1?(P-1)/(i<<1):(P-1-(P-1)/(i<<1)));
        for(int j=0;j<n;j+=i<<1){
            ll w=1;
            for(int k=0;k<i;k++,w=w*wn%P){
                ll x=a[j+k],y=w*a[j+k+i]%P;
                a[j+k]=(x+y)%P,a[j+k+i]=(x-y+P)%P;
            }
        }
    }
    if(f==-1) for(int i=0;i<n;i++) a[i]=(a[i]*_n)%P;
}

//二进制反转
inline void getrev(int n){
    int l=18;
    while(((1<<l)&n)==0) l--;
    for(int i=0;i<n;i++) r[i]=(r[i>>1]>>1)|((i&1)<<l-1);
}
//把a*b的值给d,n为d的长度
void mul(int d[],int a[],int b[],int n){ 
    static int c1[N],c2[N];
    for(int i=0;i<n;i++) c1[i]=a[i],c2[i]=b[i];
    getrev(n);
    NTT(c1,n,1);
    NTT(c2,n,1);
    for(int i=0;i<n;i++) d[i]=(ll)c1[i]*c2[i]%P;
    NTT(d,n,-1);
}

多项式求逆

\[A^{-1}(x)\equiv A^{-1}_0(x)(2-B(x)*A^{-1}_0(x))\pmod {x^n} \]

void getinv(int d[],int a[],int n){  
    static int t[N];
    if(n==1){d[0]=ksm(a[0],P-2);return;}
    getinv(d,a,n>>1);
    for(int i=0;i<n;i++) t[i]=a[i],t[i+n]=0;
    getrev(n<<1);
    NTT(t,n<<1,1);
    NTT(d,n<<1,1);
    for(int i=0;i<n<<1;i++) d[i]=(ll)d[i]*(2-(ll)t[i]*d[i]%P+P)%P;
    NTT(d,n<<1,-1);
    for(int i=n;i<n<<1;i++) d[i]=0;
}

##练习 - luogu P4238 【模板】多项式求逆


多项式开方

\[B(x)=\frac{A(x)+B_0^2(x)}{2B_0(x)} \]


##练习 - -[【BZOJ3625】【CF438E】小朋友和二叉树](https://gitee.com/vsejgfb/codes/ew5mqh9r2ivg80j4sck3f15)(拿到了rank倒1QWQ)

多项式求ln

\[lnA(x)=\int (lnA(x))'=\int\frac{A'(x)}{A(x)} \]

void getln(int d[],int a[],int n){
    static int c1[N],c2[N];
    for(int i=0;i<n<<1;i++) c1[i]=c2[i]=0;
    for(int i=0;i<n-1;i++) c1[i]=(ll)(i+1)*a[i+1]%P;
    getinv(c2,a,n);
    mul(d,c1,c2,n<<1);
    for(int i=n-1;i;i--) d[i]=(ll)d[i-1]*inv[i]%P;d[0]=0;
    for(int i=n;i<n<<1;i++) d[i]=0;
}
     

多项式求exp

\[f(x)\equiv e^{A(x)}\pmod{x^n} \]

\[f(x)=f_0(x)(1-lnf_0(x)+A(x)) \]

void getexp(int d[],int a[],int n){
    if(n==1){d[0]=1;return;}
    static int t[N];
    getexp(d,a,n>>1); 
    for(int i=0;i<n<<1;i++) t[i]=0; 
    getln(t,d,n);
    for(int i=0;i<n;i++) t[i]=(a[i]-t[i]+P)%P;
    t[0]=(t[0]+1)%P;
    mul(d,d,t,n<<1);
    for(int i=n;i<n<<1;i++) d[i]=0;
}

多项式求幂

\[A^k(x)\equiv e^{klnA(x)}\pmod{x^n} \]

void getpow(int a[],int k,int n){
    static int t[N];
    for(int i=0;i<n;i++) t[i]=0;
    getln(t,a,n);
    for(int i=0;i<n;i++) t[i]=(ll)t[i]*k%P;
    for(int i=0;i<n;i++) a[i]=0;
    getexp(a,t,n);
}

多项式除法


拉格朗日反演

\[G(F(x))=x \]

\[[x^n]F(x)=\frac1n[x^{n-1}](\frac x{G(x)})^n \]

练习


posted @ 2018-07-26 08:56  LSQ647  阅读(141)  评论(0编辑  收藏  举报