UOJ 34
终于把板子更新到正常的版本了。
FFT :
#include <bits/stdc++.h>
using namespace std;
const double pi=acos(-1.0);
typedef complex<double>E;
int n,m,x,L,mn;
int R[1<<18];
E a[1<<18],b[1<<18];
int c[1<<18];
void fft(E a[],int op){
for(int i=0;i<n;i++)if(i<R[i])swap(a[i],a[R[i]]);
for(int i=1;i<n;i<<=1){
E wn(cos(pi/i),op*sin(pi/i));
for(int j=0;j<n;j+=(i<<1)){
E w(1,0);
for(int k=0;k<i;k++,w*=wn){
E x=a[j+k],y=w*a[j+k+i];
a[j+k]=x+y;a[j+k+i]=x-y;
}
}
}
if(op==-1)for(int i=0;i<n;i++)a[i]/=n;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=0;i<=n;i++){
scanf("%d",&x);
a[i]=E(x,0);
}
for(int i=0;i<=m;i++){
scanf("%d",&x);
b[i]=E(x,0);
}
mn=n=n+m+1;
while(n!=(n&-n))n+=n&-n;
L=31-__builtin_clz(n);
for(int i=0;i<n;i++)R[i]=(R[i>>1]>>1)|((i&1)<<(L-1));
fft(a,1);fft(b,1);
for(int i=0;i<n;i++)a[i]*=b[i];
fft(a,-1);
for(int i=0;i<n;i++)c[i]=(int)(a[i].real()+0.5);
for(int i=0;i<mn;i++)printf("%d%c",c[i],i==mn-1?'\n':' ');
}
FNT :
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const long long mod=998244353;
ll power(ll n,ll p){
ll ans=1;
ll base=n;
while(p){
if(p&1)ans=ans*base%mod;
p>>=1;
base=base*base%mod;
}
return ans;
}
int n,m,x,L,mn;
int R[1<<18];
ll a[1<<18],b[1<<18];
int c[1<<18];
void fnt(ll a[],int op){
for(int i=0;i<n;i++)if(i<R[i])swap(a[i],a[R[i]]);
for(int i=1;i<n;i<<=1){
ll wn=power(3,(mod-1)/(i<<1));
if(op<0)wn=power(wn,mod-2);
for(int j=0;j<n;j+=(i<<1)){
ll w=1;
for(int k=0;k<i;k++,w=w*wn%mod){
ll x=a[j+k],y=w*a[j+k+i]%mod;
a[j+k]=(x+y)%mod;a[j+k+i]=(x-y+mod)%mod;
}
}
}
if(op==-1){
ll inv=power(n,mod-2);
for(int i=0;i<n;i++){
a[i]=a[i]*inv%mod;
}
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i=0;i<=n;i++){
scanf("%lld",&a[i]);
}
for(int i=0;i<=m;i++){
scanf("%lld",&b[i]);
}
mn=n=n+m+1;
while(n!=(n&-n))n+=n&-n;
L=31-__builtin_clz(n);
for(int i=0;i<n;i++)R[i]=(R[i>>1]>>1)|((i&1)<<(L-1));
fnt(a,1);fnt(b,1);
for(int i=0;i<n;i++)a[i]=a[i]*b[i]%mod;
fnt(a,-1);
for(int i=0;i<mn;i++)printf("%lld%c",a[i],i==mn-1?'\n':' ');
}