-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathntt.sublime-snippet
99 lines (68 loc) · 1.73 KB
/
ntt.sublime-snippet
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
<snippet>
<content><![CDATA[
namespace NTT {
// for mod 998244353
vector<ll> aux;
ll binexp(ll a, ll b) {
if (b == 0) return 1ll;
if (b == 1) return a % MOD;
if (b % 2) return (a * binexp(a, b - 1)) % MOD;
return binexp((a*a)%MOD, b/2);
}
vector<ll> dft(vector<ll> a, bool rev) {
int N = a.size();
aux.resize(N);
for (int n = N; n > 1; n /= 2) {
int c = 0;
for (int i = 0; i < N; i += n) {
for (int j = 0; j < n; j += 2)
aux[c++] = a[i + j];
for (int j = 1; j < n; j += 2)
aux[c++] = a[i + j];
}
swap(aux, a);
}
for (int n = 2; n <= N; n *= 2) {
ll mul = binexp(3, (MOD - 1) / n);
if (rev) mul = binexp(mul, MOD - 2);
for (int i = 0; i < N; i += n) {
ll cp = 1;
for (int j = 0; j < n; j++) {
int ps = n / 2;
ll cv = a[i + (j % ps)]; // even
cv += (cp * a[i + ps + (j % ps)]) % MOD; // odd
cv %= MOD;
aux[i + j] = cv;
cp *= mul;
cp %= MOD;
}
}
swap(a, aux);
}
if (rev) {
ll ninv = binexp(N, MOD - 2);
for (ll &i : a)
i *= ninv, i %= MOD;
}
return a;
}
vector<ll> convolution(vector<ll> a, vector<ll> b) {
int cs = max(a.size(), b.size()) * 2;
int n = 1; while (n < cs) n *= 2;
while (a.size() < n) a.push_back(0);
while (b.size() < n) b.push_back(0);
a = dft(a, 0); b = dft(b, 0);
vector<ll> res;
for (int i = 0; i < a.size(); i++)
res.push_back((a[i] * b[i]) % MOD);
res = dft(res, 1);
while (res.back() == 0) res.pop_back();
return res;
}
}
]]></content>
<!-- Optional: Set a tabTrigger to define how to trigger the snippet -->
<tabTrigger>ntt</tabTrigger>
<!-- Optional: Set a scope to limit where the snippet will trigger -->
<!-- <scope>source.python</scope> -->
</snippet>