Skip to content

Commit 3fe590e

Browse files
committed
Added divide, inverse, mod, derive, and integr
1 parent 8bd2091 commit 3fe590e

File tree

3 files changed

+54
-5
lines changed

3 files changed

+54
-5
lines changed

content/number-theory/ModularArithmetic.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
const ll mod = 17; // change to something else
1414
struct Mod {
1515
ll x;
16+
Mod():x(0) {}
1617
Mod(ll xx) : x(xx) {}
1718
Mod operator+(Mod b) { return Mod((x + b.x) % mod); }
1819
Mod operator-(Mod b) { return Mod((x - b.x + mod) % mod); }
@@ -27,4 +28,5 @@ struct Mod {
2728
Mod r = *this ^ (e / 2); r = r * r;
2829
return e&1 ? *this * r : r;
2930
}
31+
operator ll(){ return x; }
3032
};

content/numerical/FFTPolynomial.h

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,24 @@
55
*/
66
#pragma once
77

8+
#include "../number-theory/ModularArithmetic.h"
89
#include "FastFourierTransform.h"
10+
#include "FastFourierTransformMod.h"
911

10-
typedef double num;
12+
typedef Mod num;
1113
typedef vector<num> poly;
14+
vector<Mod> conv(vector<Mod> a, vector<Mod> b) {
15+
auto res = convMod<mod>(vl(all(a)), vl(all(b)));
16+
return vector<Mod>(all(res));
17+
}
1218
poly &operator+=(poly &a, poly &b) {
1319
a.resize(max(sz(a), sz(b)));
14-
rep(i,0,sz(b)) a[i] += b[i];
20+
rep(i,0,sz(b)) a[i] = a[i] + b[i];
1521
return a;
1622
}
1723
poly &operator-=(poly &a, poly b) {
1824
a.resize(max(sz(a), sz(b)));
19-
rep(i,0,sz(b)) a[i] -= b[i];
25+
rep(i,0,sz(b)) a[i] = a[i] - b[i];
2026
return a;
2127
}
2228
poly &operator*=(poly &a, poly &b) { return a = conv(a, b); }
@@ -26,3 +32,44 @@ poly &operator*=(poly &a, poly &b) { return a = conv(a, b); }
2632
return c oe b; \
2733
}
2834
OP(*, *=) OP(+, +=) OP(-, -=);
35+
poly modK(poly a, int k) { return {a.begin(), a.begin() + min(k, sz(a))}; }
36+
poly inverse(poly A) {
37+
poly B = poly({num(1) / A[0]});
38+
while (sz(B) < sz(A))
39+
B = modK(B * (poly({num(2)}) - A * B), 2 * sz(B));
40+
return modK(B, sz(A));
41+
}
42+
poly &operator/=(poly &a, poly &b) {
43+
if (sz(a) < sz(b))
44+
return a = {};
45+
int s = sz(a) - sz(b) + 1;
46+
reverse(all(a)), reverse(all(b));
47+
a.resize(s), b.resize(s);
48+
a = a * inverse(b);
49+
a.resize(s), reverse(all(a));
50+
return a;
51+
}
52+
OP(/, /=)
53+
poly &operator%=(poly &a, poly &b) {
54+
if (sz(a) < sz(b))
55+
return a;
56+
poly c = (a / b) * b;
57+
a.resize(sz(b) - 1);
58+
rep(i, 0, sz(a)) a[i] = a[i] - c[i];
59+
return a;
60+
}
61+
OP(%, %=)
62+
poly deriv(poly a) {
63+
if (a.empty())
64+
return {};
65+
poly b(sz(a) - 1);
66+
rep(i, 1, sz(a)) b[i - 1] = a[i] * num(i);
67+
return b;
68+
}
69+
poly integr(poly a) {
70+
if (a.empty())
71+
return {};
72+
poly b(sz(a) + 1);
73+
rep(i, 0, sz(a) + 1) b[i + 1] = a[i] / num(i + 1);
74+
return b;
75+
}

content/numerical/FastFourierTransformMod.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ template <int M> vl convMod(const vl &a, const vl &b) {
1818
vl res(sz(a) + sz(b) - 1);
1919
int B=32-__builtin_clz(sz(res)), n = 1<<B, cut=int(sqrt(M));
2020
vector<C> L(n), R(n), outs(n), outl(n), rt;
21-
rep(i,0,sz(a)) L[i] = C(a[i] / cut, a[i] % cut);
22-
rep(i,0,sz(b)) R[i] = C(b[i] / cut, b[i] % cut);
21+
rep(i,0,sz(a)) L[i] = Cd(a[i] / cut, a[i] % cut);
22+
rep(i,0,sz(b)) R[i] = Cd(b[i] / cut, b[i] % cut);
2323
fft(L, n, B, rt), fft(R, n, B, rt);
2424
rep(i,0,n) {
2525
int j = -i & (n - 1);

0 commit comments

Comments
 (0)