求助多项式exp
  • 板块学术版
  • 楼主1lgorithm
  • 当前回复0
  • 已保存回复0
  • 发布时间2021/3/11 21:52
  • 上次更新2023/11/5 02:11:24
查看原帖
求助多项式exp
287355
1lgorithm楼主2021/3/11 21:52

对着板子打的,调了半天了

#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long ll;
ll a[4000001],b[4000001];
int l,r[4000001],limit=1;
ll c[4000001];
ll d[4000001];
const int mod=998244353;
ll add(ll a,ll b){return (a+b)%mod;}
ll sub(ll a,ll b){return (a-b+mod)%mod;}
ll qpmod(ll a,ll b,ll p){
	ll ans=1%p;
	while(b){
		if(b&1) ans=ans*a%p;
		a=a*a%p;
		b>>=1;
	}
	return ans;
}
void NTT(long long *a,ll limit,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=qpmod(3,(mod-1)/(mid<<1),mod);
		if(type==-1) wn=qpmod(wn,mod-2,mod);
		for(int R=mid<<1,j=0;j<limit;j+=R){
			ll w=1;
			for(int k=0;k<mid;++k,w=w*wn%mod){
				int x=a[j+k],y=w*a[j+mid+k]%mod;
				a[j+k]=add(x,y);
				a[j+mid+k]=sub(x,y);
			}
		}
	}
	if(type==1) return ;
	ll inv=qpmod(limit,mod-2,mod);
	for(int i=0;i<limit;++i) a[i]=a[i]*inv%mod;
}
void inv(ll *a,ll *b,int n){
	if(n==1) b[0]=qpmod(a[0],mod-2,mod);
	else{
		inv(a,b,(n+1)>>1);
		limit=1,l=0;
		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=0;i<n;++i) c[i]=a[i];
		for(int i=n;i<=limit;++i) c[i]=0;
		NTT(c,limit,1),NTT(b,limit,1);
		for(int i=0;i<limit;++i){
			b[i]=(2-b[i]*c[i]%mod+mod)%mod*b[i]%mod;
		}
		NTT(b,limit,-1);
		for(int i=n;i<limit;++i) b[i]=0;
	}
}
void ln(ll *a,ll *b,int n){
	inv(a,b,n);
	for(int i=0;i<n;++i) c[i]=a[i];
	limit=1,l=0;
	while(limit<n*2) limit<<=1,++l;
	for(int i=n;i<limit;++i) c[i]=0;
	for(int i=0;i<limit;++i)
		r[i]=(r[i>>1]>>1)|((i&1)<<(l-1)),c[i]=c[i+1]*(i+1)%mod;
	NTT(c,limit,1);
	NTT(b,limit,1);
	for(int i=0;i<limit;++i){
		b[i]=c[i]*b[i]%mod;
	}
	NTT(b,limit,-1);
	for(int i=n;i>0;--i){
		b[i]=b[i-1]*qpmod(i,mod-2,mod)%mod;
	}
	b[0]=0;
}
void exp(ll *a,ll *b,int n){
	if(n==1){
		b[0]=1;
		return ;
	}
	exp(a,b,n+1>>1);
	ln(b,c,n);
	for(int i=0;i<n;++i) c[i]=sub(a[i],c[i]);
	++c[0];
	ll limit=1,l=0;
	while(limit<n*2) limit<<=1,++l;
	for(int i=0;i<limit;++i)
		r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
	NTT(b,limit,1),NTT(c,limit,1);
	for(int i=0;i<limit;++i)
		b[i]=b[i]*c[i]%mod;
	NTT(b,limit,-1);
	for(int i=n;i<limit;++i) b[i]=c[i]=0;
}
int main(){
	int n;
	cin>>n;
	for(int i=0;i<n;i++) cin>>a[i];
	exp(a,b,n);
	for(int i=0;i<n;++i) cout<<b[i]<<' ';
}
2021/3/11 21:52
加载中...