板子
杂七杂八的数学题板子:
namespace Math{
const int N=1e6+5;
const int p=998244353;
inline int mul(int a,int b){
return ((1LL*((a%p+p)%p))*(1LL*((b%p+p)%p)))%p;
}
inline void mult(int &a,int b){
return a=mul(a,b),void();
}
inline int qpow(int a,int b){
int res=1;
while(b){
if(b&1)mult(res,a);
mult(a,a),b>>=1;
}
return res;
}
inline int inv(int x){
return qpow(x,p-2);
}
int mem[N]={1};
inline int jc(int x){
if(mem[x])return mem[x];
return mem[x]=mul(x,jc(x-1));
}
inline int C(int n,int m){
if(n<m)return 0;
return mul(jc(n),inv(mul(jc(m),jc(n-m))));
}
int tot;
int pri[N],phi[N],e[N];
bool np[N];
inline void init(int n){
for(int i=2;i<=n;++i){
if(!np[i])phi[i]=i-1,e[i]=pri[++tot]=i;
for(int j=1;j<=tot&&i*pri[j]<=n;++j){
np[i*pri[j]]=1,e[i*pri[j]]=pri[j];
if(!(i%pri[j])){phi[i*pri[j]]=phi[i]*pri[j];break ;}
phi[i*pri[j]]=phi[i]*(pri[j]-1);
}
}
return phi[1]=1,void();
}
inline int qryphi(int x){
int res=x;
for(int i=2;i<=x/i;++i){
if(x%i)continue ;
(res*=(i-1))/=i;
while(!(x%i))x/=i;
}
if(x>1)(res*=(x-1))/=x;
return res;
}
}using namespace Math;
FFT(迭代):
namespace FFT{
#define db double
const int N=2e6+5;
const db PI=acos(-1);
int n,m;
int lim=1,idx;
int r[N<<1];
struct cp{
db x,y;
friend cp operator + (const cp &a,const cp &b){
return {a.x+b.x,a.y+b.y};
}
friend cp operator - (const cp &a,const cp &b){
return {a.x-b.x,a.y-b.y};
}
friend cp operator * (const cp &a,const cp &b){
return {a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x};
}
cp& operator*=(const cp &b){
return *this=*this*b,*this;
}
}A[N<<1],B[N<<1];
inline void init(){
while(lim<=n+m)lim<<=1,++idx;
for(int i=0;i<lim;++i)r[i]=((r[i>>1]>>1)|((i&1)<<(idx-1)));
return ;
}
inline void fft(cp *f,int op){
for(int i=0;i<lim;++i)if(i<r[i])swap(f[i],f[r[i]]);
for(int i=1;i<lim;i<<=1){
cp wn={cos(PI/i),op*sin(PI/i)};
for(int j=0;j<lim;j+=(i<<1)){
cp w={1.0,0.0};
for(int k=0;k<i;++k,w*=wn){
cp y=f[j+k],z=w*f[i+j+k];
f[j+k]=y+z,f[i+j+k]=y-z;
}
}
}
return ;
}
inline void solve(){
n=read(),m=read();init();
for(int i=0;i<=n;++i)A[i].x=read();
for(int i=0;i<=m;++i)B[i].x=read();
fft(A,1),fft(B,1);
for(int i=0;i<lim;++i)A[i]*=B[i];
fft(A,-1);
for(int i=0;i<n+m+1;++i)printf("%d ",(int)(A[i].x/lim+0.5));
return printf("\n"),void();
}
}using namespace FFT;
NTT:
namespace NTT{
const int N=2e6+5;
const int p=998244353;
const int g=3,inv_g=332748118;
int n,m;
int lim=1,idx;
int A[N<<1],B[N<<1];
int r[N<<1];
inline int mul(int a,int b){
return (1LL*a)*(1LL*b)%p;
}
inline void mult(int &a,int b){
return a=mul(a,b),void();
}
inline int qpow(int a,int b){
int res=1;
while(b){
if(b&1)mult(res,a);
mult(a,a),b>>=1;
}
return res;
}
inline int inv(int x){
return qpow(x,p-2);
}
inline void init(){
while(lim<=n+m)lim<<=1,++idx;
for(int i=0;i<lim;++i)r[i]=((r[i>>1]>>1)|((i&1)<<(idx-1)));
return ;
}
inline void ntt(int *f,int op){
for(int i=0;i<lim;++i)if(i<r[i])swap(f[i],f[r[i]]);
for(int i=1;i<lim;i<<=1){
int wn=qpow((~op)?g:inv_g,(p-1)/(i<<1));
for(int j=0;j<lim;j+=(i<<1)){
int w=1;
for(int k=0;k<i;++k,mult(w,wn)){
int y=f[j+k],z=mul(w,f[i+j+k]);
f[j+k]=(y+z)%p,f[i+j+k]=(y-z+p)%p;
}
}
}
if(~op)return ;
int inv_lim=inv(lim);
for(int i=0;i<lim;++i)mult(f[i],inv_lim);
return ;
}
inline void solve(){
n=read(),m=read();init();
for(int i=0;i<=n;++i)A[i]=read();
for(int i=0;i<=m;++i)B[i]=read();
ntt(A,1),ntt(B,1);
for(int i=0;i<lim;++i)mult(A[i],B[i]);
ntt(A,-1);
for(int i=0;i<=n+m;++i)printf("%d ",A[i]);
return printf("\n"),void();
}
}using namespace NTT;

浙公网安备 33010602011771号