多項式全家桶-更新中
阿新 • • 發佈:2020-09-02
多項式全家桶:
- 多項式加法(省略)
- 多項式減法(省略)
- 多項式乘法
- 多項式取逆
- 多項式取商、取模(未完成)
- 多項式求導
- 多項式積分
- 多項式對數
- 多項式開方(完成非常數項)
- 多項式指數(未完成)
- 多項式冪次(未完成)
- 多項式開 \(k\) 次方(未完成)
- 多項式三角函式(未完成)
- 多項式反三角函式(未完成)
#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; }