Kyopro Library
 
読み取り中…
検索中…
一致する文字列を見つけられません
ntt998.hpp
[詳解]
1#include"../../kyopro_library/template.hpp"
2#include"../../kyopro_library/mod/modint.hpp"
3
4/// @brief 数論変換
5/// @note O(N log(N))
6/// @details f(x) = Σ a[i]x^i, w^N = 1 とすると、F(t) = Σ f(w^i)t^i の各係数 mod 998244353 に変換する
7void NTT998(vector<Mod998>& a, bool inv=false) {
8 int n=a.size(),h=0;
9 while((1<<h)<n) h++;
10 for(int i=0; i<n; i++) {
11 int j=0;
12 // ビットを逆に
13 for(int k=0; k<h; k++) j|=(i>>k&1)<<(h-1-k);
14 if(i<j) swap(a[i],a[j]);
15 }
16
17 const vector<Mod998> rt={1,998244352,911660635,372528824,929031873,452798380,922799308,781712469,476477967,166035806,258648936,584193783,63912897,350007156,666702199,968855178,629671588,24514907,996173970,363395222,565042129,733596141,267099868,15311432};
18 const vector<Mod998> irt={1,998244352,86583718,509520358,337190230,87557064,609441965,135236158,304459705,685443576,381598368,335559352,129292727,358024708,814576206,708402881,283043518,3707709,121392023,704923114,950391366,428961804,382752275,469870224};
19
20 for(int b=1,t=1; b<n; b<<=1,t++) {
21 Mod998 w=1,base=inv?irt[t]:rt[t];
22 for(int j=0; j<b; j++) {
23 // w := 1 の b 乗根の j 乗
24 for(int k=0; k<n; k+=b*2) {
25 Mod998 s=a[j+k],t=a[j+k+b]*w;
26 a[j+k]=s+t,a[j+k+b]=s-t;
27 }
28 w*=base;
29 }
30 }
31
32 if(inv) {
33 Mod998 inv_n=Mod998(n).inv();
34 for(int i=0; i<n; i++) a[i]*=inv_n;
35 }
36}
37
38/// @brief AとBの畳み込み C[i] = Σ A[j]B[i-j] mod 998244353 を返す
39/// @note O(N log(N))
40/// @attention |a|+|b| <= 2^23 が必要
41vector<Mod998> Convolve998(vector<Mod998> a,vector<Mod998> b) {
42 int n=1;
43 while(n+1<a.size()+b.size()) n<<=1;
44
45 vector<Mod998> fa(n),fb(n);
46 for(int i=0; i<a.size(); i++) fa[i]=a[i];
47 for(int i=0; i<b.size(); i++) fb[i]=b[i];
48
49 NTT998(fa); NTT998(fb);
50 for(int i=0; i<n; i++) fa[i]*=fb[i];
51 NTT998(fa,true);
52
53 while(fa.size()+1>a.size()+b.size()) fa.pop_back();
54 return fa;
55}
void NTT998(vector< Mod998 > &a, bool inv=false)
数論変換
Definition ntt998.hpp:7
vector< Mod998 > Convolve998(vector< Mod998 > a, vector< Mod998 > b)
AとBの畳み込み C[i] = Σ A[j]B[i-j] mod 998244353 を返す
Definition ntt998.hpp:41