萌新求助 多项式 ln
查看原帖
萌新求助 多项式 ln
311306
dk_qwq楼主2023/4/12 08:49

RT,T掉了后面7个点,感觉是求逆有问题

#include<iostream>
#include<cstdio>
using namespace std;
namespace INPUT{
	char buf[1<<20],*p1,*p2;
	#define gc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin)),p1==p2?EOF:*p1++)
}
using namespace INPUT;
template<typename T>
inline T read(){
	T x=0,p=1;
	char ch=gc();
	while(ch<'0'||ch>'9'){
		if(ch=='-') p=-1;
		ch=gc();
	}
	while(ch>='0'&&ch<='9'){
		x=(x<<3)+(x<<1)+(ch^48);
		ch=gc();
	}
	return x*p;
}
const int N=4e5+5;
#define ll long long
const ll g=3,p=998244353;
ll gi;
ll ExGcd(ll a,ll b,ll &x,ll &y){
	if(!b) return x=1,y=0,a;
	ll r=ExGcd(b,a%b,y,x);
	y-=(a/b)*x;
	return r;
}
ll Inv(ll a,ll m){
	ll x,y;
	ExGcd(a,m,x,y);
	return (x%m+m)%m;
}
ll qpow(ll x,ll k){
	ll ans=1;
	while(k){
		if(k&1) ans=(ans*x)%p;
		x=(x*x)%p,k>>=1;
	}
	return ans;
}
int r[N],limit,l;
void NTT(ll *A,int type){
	for(int i=0;i<limit;i++)
		if(i<r[i]) swap(A[i],A[r[i]]);
	for(int mid=1;mid<limit;mid<<=1){
		ll Wn=qpow(type==-1?g:gi,(p-1)/(mid<<1));
		for(int R=mid<<1,j=0;j<limit;j+=R){
			ll w=1;
			for(int k=0;k<mid;k++,w=(w*Wn)%p){
				ll x=A[j+k],y=w*A[j+k+mid];
				A[j+k]=(x+y)%p,A[j+k+mid]=(x-y+p)%p;
			}
		}
	}
	if(type==-1){
		ll Ln=Inv(limit,p);
		for(int i=0;i<limit;i++) A[i]=(A[i]*Ln)%p;
	}
}
ll B[N],dB[N];
void Inv(ll *A){
	for(int i=0;i<limit;i++) B[i]=0,dB[i]=0;
	dB[0]=Inv(A[0],p);
	for(int mid=1;mid<limit;mid<<=1){
		for(int i=0;i<mid;i++) B[i]=A[i];
		for(int i=mid;i<limit;i++) B[i]=0;
		NTT(B,1),NTT(dB,1);
		for(int i=0;i<limit;i++) dB[i]=(2ll-dB[i]*B[i]%p+p)%p*dB[i]%p;
		NTT(dB,-1);
		for(int i=mid;i<limit;i++) dB[i]=0;
	}
	for(int i=0;i<limit;i++) A[i]=dB[i];
}
int n;
ll A[N],f[N];
int main(){
//	freopen("P4725.in","r",stdin);
	gi=Inv(g,p);
	n=read<int>();
	for(int i=0;i<n;i++) f[i]=A[i]=read<int>();
	limit=1;
	while(limit<=n*2) limit<<=1,l++;
	for(int i=0;i<limit;i++) r[i]=((r[i>>1]>>1)|((i&1)<<(l-1)));
	for(int i=1;i<limit;i++) f[i-1]=(f[i]*i)%p,f[i]=0,
	Inv(A);
	NTT(f,1),NTT(A,1);
	for(int i=0;i<limit;i++) f[i]=(f[i]*A[i])%p;
	NTT(f,-1);
	for(int i=limit-1;i>=0;i--) f[i+1]=(f[i]*Inv(i+1,p))%p,f[i]=0;
	for(int i=0;i<n;i++) printf("%lld%c",(f[i]+p)%p," \n"[i==n]);
}
2023/4/12 08:49
加载中...