1. 程式人生 > 實用技巧 >多項式全家桶-更新中

多項式全家桶-更新中

多項式全家桶:

  1. 多項式加法(省略)
  2. 多項式減法(省略)
  3. 多項式乘法
  4. 多項式取逆
  5. 多項式取商、取模(未完成)
  6. 多項式求導
  7. 多項式積分
  8. 多項式對數
  9. 多項式開方(完成非常數項)
  10. 多項式指數(未完成)
  11. 多項式冪次(未完成)
  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//開方

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 ll sqrtM(ll n) { return n==1; }
inline void sqrt(ll f[MAXN],ll g[MAXN],ll N){
    static ll p[MAXN],inv2=MOD+1>>1;
    if(N==1){
        g[0]=sqrtM(f[0]);
        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

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

    cin>>N;
    for(int i=0;i<N;i++) cin>>A[i];
    ln(A,B,N);
    for(int i=0;i<N;i++) cout<<B[i]<<" ";
    cout<<endl;
    return 0;
}