萌新初学倍增FFT,求调
查看原帖
萌新初学倍增FFT,求调
553501
可爱的小棉羊楼主2024/4/22 17:02

用了 nn 特大的数据拍都没问题。

#include<bits/stdc++.h>
using namespace std;
const int mod=998244353,g=3,ing=332748118;
long long fpow(long long a,long long b){
	long long ans=1;
	while(b){
		if(b&1)ans=ans*a%mod;
		a=a*a%mod;
		b>>=1;
	} 
	return ans;
}
long long lim,n,res[80000];
long long f[3][80000];
long long k;
void ntt(long long* a,int n,bool f){
	for(int i=0;i<n;i++)if(i<res[i])swap(a[i],a[res[i]]);
	for(int h=1;h<n;h<<=1){
		long long wn;
		if(f==0)wn=fpow(g,(mod-1)/(h<<1));
		else wn=fpow(ing,(mod-1)/(h<<1));
		for(int j=0;j<n;j+=(h<<1)){
			long long w=1;
			for(int k=0;k<h;k++,w=(w*wn)%mod){
				long long x=a[j+k]%mod,y=a[j+h+k]*w%mod;
				a[j+k]=(x+y)%mod;
				a[j+h+k]=(x-y+mod)%mod;
			}
		}
	}
	if(f==1){
		long long inv=fpow(n,mod-2);
		for(int i=0;i<n;i++)a[i]=a[i]*inv%mod;
	}
}
int bas=2,s=1;
long long h[5][80005];
void shift(){
	for(int i=0;i<bas;i++)h[0][i]=h[1][i]=h[2][i]=h[3][i]=h[4][i]=0;
	ntt(f[0],bas,0);
	ntt(f[1],bas,0);
	ntt(f[2],bas,0);
	for(int i=0;i<bas;i++){
		h[0][i]=f[0][i]*f[0][i]%mod;
		h[1][i]=f[1][i]*f[1][i]%mod;
		h[2][i]=f[2][i]*f[2][i]%mod;
		h[3][i]=f[0][i]*f[1][i]%mod;
		h[4][i]=f[2][i]*f[1][i]%mod;
		f[0][i]=f[1][i]=f[2][i]=0;
	}
	ntt(h[0],bas,1);
	ntt(h[1],bas,1);
	ntt(h[2],bas,1);
	ntt(h[3],bas,1);
	ntt(h[4],bas,1);
	for(int i=0;i<bas;i++){
		f[0][i]=h[0][i];
		f[1][i]=h[3][i];
		f[2][i]=h[1][i];
	}
	for(int i=1;i<bas;i++){
		f[0][i]=(f[0][i]+h[1][i-1])%mod;
		f[1][i]=(f[1][i]+h[4][i-1])%mod;
		f[2][i]=(f[2][i]+h[2][i-1])%mod;
	}
	for(int i=k+1;i<bas;i++)f[0][i]=f[1][i]=f[2][i]=0;
}
void setbit(){
	for(int i=0;i<bas;i++)h[0][i]=f[0][i];
	for(int i=1;i<bas;i++)h[0][i]=(h[0][i]+f[0][i-1]+f[1][i-1])%mod;
	for(int i=0;i<bas;i++){
		f[2][i]=f[1][i];
		f[1][i]=f[0][i];
		f[0][i]=h[0][i];
		
	}
}
int main(){
//	freopen("old.txt","w",stdout);
	cin>>n>>k;
	lim=log2(n);
	f[0][0]=f[1][0]=f[0][1]=1;
	
	while(bas<=(k<<1)){
		bas<<=1;
		s++;
	}
	for(int i=0;i<bas;i++)res[i]=(res[i>>1]>>1)|((i&1)<<(s-1));
//	for(int i=0;i<bas;i++)cout<<res[i]<<" ";
//	cout<<endl;
	for(int i=lim-1;i>=0;i--){
		shift();
		
		if(n&(1<<i))setbit();
//		for(int j=0;j<bas;j++)cout<<f[0][j]<<" ";
//		cout<<endl;
	}
	
	for(int i=1;i<=k;i++)cout<<f[0][i]<<" ";
	
	
}
//1000000000 32767
2024/4/22 17:02
加载中...