Skip to content

Commit ce6fc4d

Browse files
committed
add Number Theoretic Transform
1 parent cefb6c8 commit ce6fc4d

File tree

1 file changed

+53
-0
lines changed

1 file changed

+53
-0
lines changed
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#include <cstdio>
2+
#include <cassert>
3+
#include <algorithm>
4+
5+
namespace NTT {
6+
using ll = long long;
7+
const ll P = 2013265921, g = 31;
8+
//2113929217,5; 1811939329,13; 2130706433,3; 786433,10;
9+
//1945555039024054273,5; 1231453023109121ll,3;
10+
inline ll mul_mod(ll a, ll b, ll mod) {
11+
assert(0 <= a && a < mod);
12+
assert(0 <= b && b < mod);
13+
if (mod < int(1e9)) return a * b % mod;
14+
ll k = (ll)((long double)a * b / mod);
15+
ll res = a * b - k * mod;
16+
res %= mod;
17+
if (res < 0) res += mod;
18+
return res;
19+
}
20+
ll pow_mod(ll a, ll n, ll m) {
21+
ll r = 1;
22+
for (; n; n >>= 1) {
23+
if (n & 1) r = mul_mod(r, a, m);
24+
a = mul_mod(a, a, m);
25+
}
26+
return r;
27+
}
28+
void trans(ll a[], int n, bool inv = false) {
29+
ll w = 1, d = pow_mod(g, (P - 1) / n, P), t;
30+
int i, j, c, s;
31+
if (inv) {
32+
for (i = 1, j = n - 1; i < j; std::swap(a[i++], a[j--]));
33+
for (t = pow_mod(n, P - 2, P), i = 0; i < n; ++i) {
34+
a[i] = mul_mod(a[i], t, P);
35+
}
36+
}
37+
for (s = n >> 1; s; s >>= w = 1, d = mul_mod(d, d, P)) {
38+
for (c = 0; c < s; ++c, w = mul_mod(w, d, P)) {
39+
for (i = c; i < n; i += s << 1) {
40+
t = a[i | s];
41+
a[i | s] = mul_mod((a[i] + P - t) % P, w, P);
42+
a[i] = (a[i] + t) % P;
43+
}
44+
}
45+
}
46+
for (i = 1; i < n; ++i) {
47+
for (j = 0, s = i, c = n >> 1; c; c >>= 1, s >>= 1) {
48+
j = j << 1 | s & 1;
49+
}
50+
if (i < j) std::swap(a[i], a[j]);
51+
}
52+
}
53+
}

0 commit comments

Comments
 (0)