多项式全家桶-更新中

多项式全家桶:

  1. 多项式加法(省略)
  2. 多项式减法(省略)
  3. 多项式乘法
  4. 多项式取逆
  5. 多项式取商、取模
  6. 多项式求导
  7. 多项式积分
  8. 多项式对数
  9. 多项式开方(未完成常数项)
  10. 多项式指数
  11. 多项式幂次(未完成常数项为 (0)
  12. 多项式开 (k) 次方(未完成)
  13. 多项式三角函数
  14. 多项式反三角函数
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll MOD=998244353,MAXN=1<<21;

#define MUL//乘
#define INV//逆
#define DDX//导
#define INTDX//积
#define LN//对数
#define SQRT//开方
#define ATRI//反三角
#define EXP//指数
#define TRI//三角
#define POW//幂次
#define DIV//除

inline ll fpow(ll a,ll x) { ll ans=1; for(;x;x>>=1,a=a*a%MOD) if(x&1) ans=ans*a%MOD; return ans; }
inline ll inv(ll a) { return fpow(a,MOD-2); }
ll L,invL,R[MAXN];
inline void preNTT(){
    R[1]=L>>1;
    for(int i=2;i<L;i++) R[i]=(R[i>>1]>>1)|R[i&1];
    invL=inv(L);
}
inline void NTT(ll f[MAXN],ll op){
    op=(op==1?3:inv(3));
    for(int i=0;i<L;i++) if(i<R[i]) swap(f[i],f[R[i]]);
    for(ll bas=2,lb=1,omega;omega=fpow(op,MOD>>lb),bas<=L;bas<<=1,lb++)
        for(ll l=0,mid=bas>>1;l<L;l+=bas)
            for(ll k=l,buf=1,tmp;tmp=buf*f[k+mid]%MOD,k<l+mid;k++,buf=buf*omega%MOD)
                f[k+mid]=(f[k]-tmp)%MOD,f[k]=(f[k]+tmp)%MOD;
    if(op==3){
        for(int i=0;i<L;i++) f[i]=(f[i]+MOD)%MOD;
        return ;
    }
    for(int i=0;i<L;i++) f[i]=(f[i]+MOD)*invL%MOD;
}

#ifdef MUL
inline void mul(ll f[MAXN],ll g[MAXN],ll h[MAXN],ll N,ll M){
    static ll p[MAXN],q[MAXN];
    L=N+M;
    while(L!=(L&(-L))) L+=L&(-L);
    for(int i=0;i<L;i++) p[i]=q[i]=0;
    for(int i=0;i<N;i++) p[i]=f[i];
    for(int i=0;i<M;i++) q[i]=g[i];
    preNTT();
    NTT(p,1);
    NTT(q,1);
    for(int i=0;i<L;i++) h[i]=p[i]*q[i];
    NTT(h,-1);
    for(int i=N+M;i<L;i++) h[i]=0;
}
#endif

#ifdef INV
inline void inv(ll f[MAXN],ll g[MAXN],ll N){
    static ll p[MAXN],q[MAXN];
    if(N==1){
        g[0]=inv(f[0]);
        return ;
    }
    inv(f,g,N+1>>1);
    L=1;
    while(L<(N<<1)) L<<=1;
    for(int i=0;i<L;i++) p[i]=q[i]=0;
    for(int i=0;i<N;i++) q[i]=g[i],p[i]=f[i];
    preNTT();
    NTT(p,1);
    NTT(q,1);
    for(int i=0;i<L;i++) g[i]=q[i]*(2ll-q[i]*p[i]%MOD+MOD)%MOD;
    NTT(g,-1);
    for(int i=N;i<L;i++) g[i]=0;
}
#endif

#ifdef DDX
inline void ddx(ll f[MAXN],ll g[MAXN],ll N){
    for(int i=0;i<N-1;i++) g[i]=f[i+1]*(i+1)%MOD;
    g[N-1]=0;
}
#endif

#ifdef INTDX
inline void intdx(ll f[MAXN],ll g[MAXN],ll N,ll C=0){
    for(int i=1;i<=N;i++) g[i]=f[i-1]*inv(i)%MOD;
    g[0]=C;
}
#endif

#ifdef SQRT
inline void sqrt(ll f[MAXN],ll g[MAXN],ll N,ll g0=1){
    static ll p[MAXN],inv2=MOD+1>>1;
    if(N==1){
        g[0]=g0;
        return ;
    }
    sqrt(f,g,N+1>>1);
    for(int i=0;i<N;i++) p[i]=0;
    inv(g,p,N);
    mul(f,p,p,N,N);
    for(int i=0;i<N;i++) g[i]=(g[i]+p[i])*inv2%MOD;
}
#endif

#ifdef LN
inline void ln(ll f[MAXN],ll g[MAXN],ll N){
    static ll p[MAXN],q[MAXN];
    ddx(f,p,N);
    inv(f,q,N);
    mul(p,q,p,N,N);
    for(int i=N;i<N+N;i++) p[i]=0;
    intdx(p,g,N);
}
#endif

#ifdef ATRI
inline void asin(ll f[MAXN],ll g[MAXN],ll N){
    static ll p[MAXN],q[MAXN];
    mul(f,f,q,N,N);
    for(int i=0;i<N;i++) q[i]=MOD-q[i];
    q[0]=(q[0]+1)%MOD;
    for(int i=N;i<N+N;i++) q[i]=0;
    sqrt(q,p,N);
    inv(p,q,N);
    ddx(f,p,N);
    mul(p,q,p,N,N);
    for(int i=N;i<N+N;i++) p[i]=0;
    intdx(p,g,N);
}
inline void atan(ll f[MAXN],ll g[MAXN],ll N){
    static ll p[MAXN],q[MAXN];
    mul(f,f,q,N,N);
    q[0]=(q[0]+1)%MOD;
    for(int i=N;i<N+N;i++) q[i]=0;
    inv(q,p,N);
    ddx(f,q,N);
    mul(p,q,p,N,N);
    for(int i=N;i<N+N;i++) p[i]=0;
    intdx(p,g,N);
}
#endif

#ifdef EXP
inline void exp(ll f[MAXN],ll g[MAXN],ll N,ll g0=1){
    static ll p[MAXN];
    if(N==1){
        g[0]=g0;
        return ;
    }
    exp(f,g,N+1>>1,g0);
    ln(g,p,N);
    for(int i=0;i<N;i++) p[i]=(f[i]-p[i]+MOD)%MOD;
    p[0]=(p[0]+1)%MOD;
    mul(p,g,g,N,N);
    for(int i=N;i<N+N;i++) g[i]=0;
}
#endif

#ifdef TRI
inline void tri(ll f[MAXN],ll g[MAXN],ll N,ll op){
    static ll p[MAXN],q[MAXN],inv2=MOD+1>>1,imag=fpow(3,MOD>>2);
    for(int i=0;i<N;i++) g[i]=f[i]*imag%MOD;
    exp(g,p,N);
    for(int i=0;i<N;i++) g[i]=MOD-g[i];
    exp(g,q,N);
    for(int i=0;i<N;i++) g[i]=(p[i]+op*q[i]+MOD)*inv2%MOD;
    if(op==-1) for(int i=0;i<N;i++) g[i]=(MOD-imag*g[i]%MOD)%MOD;
}
inline void sin(ll f[MAXN],ll g[MAXN],ll N) { tri(f,g,N,-1); }
inline void cos(ll f[MAXN],ll g[MAXN],ll N) { tri(f,g,N,1); }
#endif

#ifdef POW
inline ll tonum(const string &N,ll M){
    ll Ans=0;
    for(const auto &c : N) Ans=(Ans*10+c-48)%M;
    return Ans;
}
inline void pow(ll f[MAXN],ll g[MAXN],ll N,const string &K){
    static ll p[MAXN];
    ln(f,p,N);
    ll NK=tonum(K,MOD);
    for(int i=0;i<N;i++) p[i]=NK*p[i]%MOD;
    exp(p,g,N,fpow(f[0],tonum(K,MOD-1)));
}
#endif

#ifdef DIV
inline void div(ll f[MAXN],ll g[MAXN],ll q[MAXN],ll r[MAXN],ll N,ll M){
    static ll p[MAXN],t[MAXN];
    for(int i=0;i<=M;i++) t[i]=g[M-i];
    inv(t,p,N-M+1);
    for(int i=0;i<=M;i++) t[i]=0;
    for(int i=0;i<=N;i++) t[i]=f[N-i];
    for(int i=N-M+1;i<=N;i++) t[i]=0;
    mul(p,t,q,N-M+1,N-M+1);
    for(int i=N-M+1;i<L;i++) q[i]=0;
    reverse(q,q+N-M+1);
    mul(q,g,p,N-M+1,M+1);
    for(int i=N;i>=0;i--) r[i]=(f[i]-p[i]+MOD)%MOD;
}
#endif

ll N,M,A[MAXN],B[MAXN],Q[MAXN],Rr[MAXN];
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    cin>>N>>M;
    for(int i=0;i<=N;i++) cin>>A[i];
    for(int i=0;i<=M;i++) cin>>B[i];
    div(A,B,Q,Rr,N,M);
    for(int i=0;i<=N-M;i++) cout<<Q[i]<<" ";
    cout<<endl;
    for(int i=0;i<M;i++) cout<<Rr[i]<<" ";
    cout<<endl;
    return 0;
}
原文地址:https://www.cnblogs.com/JustinRochester/p/13603648.html