1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| typedef long long ll;
ll qpow(ll a,ll b,ll mod){ ll ret=1; while(b){ if(b&1) ret=ret*a%mod; a=a*a%mod; b>>=1; } return ret; }
const ll maxn=1e6; ll r[maxn]; void ntt(ll*a,ll n,ll bits,ll opt,ll g,ll mod){ for(ll i=0;i<n;i++) { r[i]=(r[i>>1]>>1)|((i&1)<<(bits-1)); if(i<r[i]) swap(a[i],a[r[i]]); } for(ll k=1;k<n;k<<=1){ ll wn=qpow(g,(mod-1)/(k<<1),mod); if(opt==-1) wn=qpow(wn,mod-2,mod); for (ll i=0;i<n;i+=(k<<1)){ for (ll j=0,w=1; j<k; j++,w=w*wn%mod){ ll x=a[i+j], y=w*a[i+j+k]%mod; a[i+j]=(x+y)%mod, a[i+j+k]=(x-y+mod)%mod; } } } if(opt==-1) { ll inv=qpow(n,mod-2,mod); for(ll i=0;i<n;i++) a[i]=a[i]*inv%mod; } }
ll cpx[maxn],cpy[maxn]; void mul(ll*x,ll*y,ll*xy,ll xn,ll yn,ll g,ll mod){ ll exn=1,bits=0; while(exn-1 < xn-1+yn-1)exn<<=1,bits++; for(ll i=0 ;i<xn ;i++)cpx[i]=x[i]; for(ll i=xn;i<exn;i++)cpx[i]=0; for(ll i=0 ;i<yn ;i++)cpy[i]=y[i]; for(ll i=yn;i<exn;i++)cpy[i]=0; ntt(cpx,exn,bits,1,g,mod); ntt(cpy,exn,bits,1,g,mod); for(ll i=0; i<exn;i++)cpx[i]=cpx[i]*cpy[i]%mod; ntt(cpx,exn,bits,-1,g,mod); for(ll i=0; i<exn;i++)xy[i]=cpx[i]; }
|