Skip to content

Commit 51d094c

Browse files
committed
add single point evaluation
1 parent dde3a43 commit 51d094c

File tree

1 file changed

+45
-0
lines changed

1 file changed

+45
-0
lines changed

mathematics/polynomial-interpolation.cc

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,48 @@ std::vector<T> interpolation(const T x[], const T y[], int n){
2020
}
2121
return ret;
2222
}
23+
24+
// f(x) is degree m - 1, given f(0), f(1), ..., f(m - 1),
25+
// return f(n) in linear time
26+
int64 evaluate(const std::vector<int64> &f, int64 n, int64 mod) {
27+
int64 m = f.size(), nn = n % mod;
28+
if (n < m) return f[n];
29+
std::vector<int64> inv(m + 1), fact(m + 1), ifact(m + 1);
30+
inv[1] = fact[0] = ifact[0] = fact[1] = ifact[1] = 1;
31+
for (int i = 2; i <= m; ++i) {
32+
inv[i] = int64(mod - mod / i) * inv[mod % i] % mod;
33+
fact[i] = (int64)i * fact[i - 1] % mod;
34+
ifact[i] = (int64)inv[i] * ifact[i - 1] % mod;
35+
}
36+
int64 ret = 0, v = 1;
37+
std::vector<int64> s(m + 1);
38+
s[m] = 1;
39+
for (int i = m - 1; i >= 0; --i) {
40+
v = (int64)v * (nn - i + mod) % mod;
41+
s[i] = (int64)s[i + 1] * (nn - i + mod) % mod;
42+
if (i == nn) s[i] = 1;
43+
}
44+
v = pow_mod(v, mod - 2, mod);
45+
for (int i = 0; i < m; ++i) {
46+
int64 inv2 = (int64)v * s[i + 1] % mod;
47+
v = (int64)v * (nn - i + mod) % mod;
48+
int64 mul = (int64)ifact[i] * ifact[m - 1 - i] % mod * inv2 % mod;
49+
if ((m - 1 - i) & 1) mul = mod - mul;
50+
if (i != nn) {
51+
ret += f[i] * mul % mod;
52+
}
53+
if (ret >= mod) ret -= mod;
54+
}
55+
for (int i = 0; i < m; ++i) {
56+
ret = (int64)ret * (nn - i + mod) % mod;
57+
}
58+
if (nn <= m - 1) {
59+
int64 extra = f[nn] * ifact[nn] % mod * ifact[m - 1 - nn] % mod;
60+
if ((m - 1 - nn) & 1) extra = mod - extra;
61+
for (int i = 0; i < m; ++i) {
62+
if (i != nn) extra = extra * (nn - i + mod) % mod;
63+
}
64+
ret = (ret + extra) % mod;
65+
}
66+
return ret;
67+
}

0 commit comments

Comments
 (0)