多项式

多项式半家桶

其中 \(G(x)\)\(\text{mod } x^n\) 下的答案, \(H(x)\)\(\text{mod } x^{\left \lceil \frac{n}{2} \right \rceil}\) 下的答案

多项式乘法逆 \(G(x)\equiv 2H(x)-F(x)H^2(x) (\text{mod } x^n)\)

实现上可以只卷 \(H(x)F(x)\) 然后再处理其他的

多项式开根 \(G(x)\equiv \frac{F(x)+H^2(x)}{2H(x)}\)

用求逆把 \(\frac{F(x)}{H(x)}\) 卷出来,其他的单独算

多项式 \(\ln\) \(G'(x)=\frac{F'(x)}{F(x)}\) 求导再积分回去

求导公式 \(x^{a'}=ax^{a-1}\) 积分公式 \(\int x^adx=\frac{1}{a+1}x^{a+1}\)

多项式 \(\exp\) \(G(x)\equiv H(x)(1-\ln H(x)+F(x))\)

这个就正常写就行

再放个板子,跑得还挺快

Code
#include<bits/stdc++.h>
#define int long long
#define rint signed
#define mod 998244353
#define i2 499122177
#define inf 0x3f3f3f3f3f3f3f3f
using namespace std;
inline int read(){
	int x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
	return x*f;
}
int n;
int f[262150],g[262150],t[262150];
inline int qpow(int x,int k){
	int res=1,base=x;
	while(k){if(k&1) res=res*base%mod;base=base*base%mod;k>>=1;}
	return res;
}
inline void md(int &x){x=(x>=mod)?x-mod:x;}
namespace POLY{
	int inv;
	int r[262150],g[262150],I[262150];
	int T[262150],A[262150],B[262150],C[262150];
	inline void init(int len,int L){
		for(int i=0;i<len;i++) r[i]=(r[i>>1]>>1)|((i&1)<<(L-1));
		g[0]=1,g[1]=qpow(3,(mod-1)/len);for(int i=2;i<len;i++) g[i]=g[i-1]*g[1]%mod;
	}
	inline void rev(int len){g[0]=1,g[1]=qpow(g[1],mod-2);for(int i=2;i<len;i++) g[i]=g[i-1]*g[1]%mod;}
	inline void ntt(int a[],int len){
		for(int i=0;i<len;i++) if(i<r[i]) swap(a[i],a[r[i]]);
		for(int d=1,t=len>>1;d<len;d<<=1,t>>=1) for(int i=0;i<len;i+=(d<<1)) for(int j=0;j<d;j++){
			int tmp=g[t*j]*a[i+j+d]%mod;
			md(a[i+j+d]=a[i+j]-tmp+mod);
			md(a[i+j]=a[i+j]+tmp);
		}
	}
	inline void INV(int F[],int G[],int n){
		G[0]=qpow(F[0],mod-2);int L,len;
		for(L=1,len=2;(len>>1)<n;){
			for(int i=0;i<len;i++) T[i]=F[i];
			len<<=1,L++;init(len,L);
			for(int i=len>>1;i<len;i++) T[i]=0;
			ntt(G,len);ntt(T,len);rev(len);
			for(int i=0;i<len;i++) G[i]=(2ll-T[i]*G[i]%mod+mod)%mod*G[i]%mod;
			ntt(G,len);inv=qpow(len,mod-2);
			for(int i=0;i<len;i++) G[i]=G[i]*inv%mod;
			for(int i=len>>1;i<len;i++) G[i]=0;
		}
		for(int i=n;i<len;i++) G[i]=0;
	}
	inline void SQRT(int F[],int G[],int n){
		G[0]=1;int L,len;
		for(L=1,len=2;(len>>1)<n;){
			len<<=1,L++;
			INV(G,A,len>>1);init(len,L);
			for(int i=0;i<len;i++) T[i]=F[i];
			for(int i=len>>1;i<len;i++) T[i]=0;
			ntt(A,len);ntt(T,len);rev(len);
			for(int i=0;i<len;i++) A[i]=A[i]*T[i]%mod;
			ntt(A,len);inv=qpow(len,mod-2);
			for(int i=0;i<len;i++) A[i]=A[i]*inv%mod;
			for(int i=0;i<len;i++) G[i]=(G[i]+A[i])*i2%mod;
			for(int i=0;i<len;i++) A[i]=0;
		}
	}
	inline void dao(int F[],int G[],int len){for(int i=1;i<len;i++) G[i-1]=i*F[i]%mod;G[len-1]=0;}
	inline void jifen(int F[],int G[],int len){for(int i=1;i<len;i++) G[i]=F[i-1]*I[i]%mod;G[0]=0;}
	inline void Ln(int F[],int G[],int n){
		dao(F,A,n);INV(F,B,n);int len=1,L=0;
		for(;len<n+n;len<<=1,L++);init(len,L);
		ntt(A,len);ntt(B,len);rev(len);
		for(int i=0;i<len;i++) A[i]=A[i]*B[i]%mod;
		ntt(A,len);inv=qpow(len,mod-2);
		for(int i=0;i<len;i++) A[i]=A[i]*inv%mod;
		jifen(A,G,n);for(int i=n;i<len;i++) G[i]=0;
		for(int i=0;i<len;i++) A[i]=B[i]=0;
	}
	inline void Exp(int F[],int G[],int n){
		G[0]=1;int L,len;
		for(L=1,len=2;(len>>1)<n;){
			len<<=1,L++;Ln(G,C,len>>1);init(len,L);
			for(int i=0;i<len;i++) md(C[i]=F[i]-C[i]+mod);C[0]++;
			for(int i=len>>1;i<len;i++) C[i]=0;
			ntt(G,len);ntt(C,len);rev(len);
			for(int i=0;i<len;i++) G[i]=G[i]*C[i]%mod;
			ntt(G,len);inv=qpow(len,mod-2);
			for(int i=0;i<len;i++) G[i]=G[i]*inv%mod;
			for(int i=len>>1;i<len;i++) G[i]=0;
		}
	}
	inline void initinv(){
		int len=1;for(;len<n+n;len<<=1);
		I[1]=1;for(int i=2;i<len;i++) I[i]=(mod-mod/i)*I[mod%i]%mod;
	}
}
signed main(){
#ifdef LOCAL
	freopen("in","r",stdin);
	freopen("out","w",stdout);
#endif
	n=read();for(int i=0;i<n;i++) f[i]=read();
	//直接调用就行
	for(int i=0;i<n;i++) printf("%lld ",g[i]);
	return 0;
}
posted @ 2022-01-24 16:29  Max_QAQ  阅读(94)  评论(1编辑  收藏  举报