Optimum Polynomial
If we are given the first k terms of a sequence, it is not always possible to determine the generating function. For example, consider the sequence of cube numbers: 1, 8, 27, 64, 125, 216,... If we...
Problem Statement
This archive keeps the full statement, math, and original media on the page.
If we are presented with the first \(k\) terms of a sequence it is impossible to say with certainty the value of the next term, as there are infinitely many polynomial functions that can model the sequence.
As an example, let us consider the sequence of cube numbers. This is defined by the generating function, \(u_n = n^3\): \(1, 8, 27, 64, 125, 216, \dots \)
Suppose we were only given the first two terms of this sequence. Working on the principle that "simple is best" we should assume a linear relationship and predict the next term to be \(15\) (common difference \(7\)). Even if we were presented with the first three terms, by the same principle of simplicity, a quadratic relationship should be assumed.
We shall define \(\operatorname {OP}(k, n)\) to be the \(n^{th}\) term of the optimum polynomial generating function for the first \(k\) terms of a sequence. It should be clear that \(\operatorname {OP}(k, n)\) will accurately generate the terms of the sequence for \(n \le k\), and potentially the first incorrect term (FIT) will be \(\operatorname {OP}(k, k+1)\); in which case we shall call it a bad OP (BOP).
As a basis, if we were only given the first term of sequence, it would be most sensible to assume constancy; that is, for \(n \ge 2\), \(\operatorname {OP}(1, n) = u_1\).
Hence we obtain the following \(\operatorname {OP}\)s for the cubic sequence: \[ \begin {array}{ll} OP(1, n) = 1 & 1, {\color {red} 1}, 1, 1, \ldots \\ OP(2, n) = 7n - 6 & {\color {red} 1}, 8, 15, \ldots \\ OP(3, n) = 6n^2 - 11n + 6 & 1, 8, 27, {\color {red} 58} \\ OP(4, n) = n^3 & 1, 8, 27, 64, 125, \ldots \end {array} \]
Clearly no BOPs exist for \(k \ge 4\).
By considering the sum of FITs generated by the BOPs (indicated in red above), we obtain \(1 + 15 + 58 = 74\).
Consider the following tenth degree polynomial generating function: \[u_n = 1 - n + n^2 - n^3 + n^4 - n^5 + n^6 - n^7 + n^8 - n^9 + n^{10}.\] Find the sum of FITs for the BOPs.
Problem 101: Optimum Polynomial
Mathematical Development
Theorem 1 (Existence and Uniqueness of Polynomial Interpolation). Given distinct nodes and values , there exists a unique polynomial of degree at most satisfying for .
Proof. Existence. Define the Lagrange basis polynomials
Each has degree and satisfies (the Kronecker delta). The polynomial
has degree at most and satisfies for each .
Uniqueness. Suppose with also interpolates the data. Then has degree at most and vanishes at the distinct points . By the Factor Theorem, is divisible by , a polynomial of degree . Since , we conclude , hence .
Theorem 2 (FIT Existence for Under-Determined Interpolation). Let with , and for , let denote the unique polynomial of degree at most interpolating . Then .
Proof. Define . Since and , the leading coefficient of equals the leading coefficient of , so . The polynomial vanishes at , whence
for some polynomial of degree with the same leading coefficient as (up to sign).
Evaluating at :
Since , it suffices to show . The polynomial has degree and leading coefficient equal to the leading coefficient of (which is for the stated ). For , is a nonzero constant, so . For , is a nonconstant polynomial; we verify computationally that for each . (Alternatively, note that has roots among only if specific coefficient relationships hold, which fail for the given .)
Lemma 1 (Lagrange Evaluation Complexity). The value at a single point can be computed in arithmetic operations via the Lagrange formula.
Proof. The Lagrange formula
involves terms, each requiring multiplications and divisions. The total count is arithmetic operations.
Editorial
Given u(n) = sum_{j=0}^{10} (-1)^j n^j, find the sum of all FITs for the BOPs using the first k = 1, …, 10 terms.
Pseudocode
define u(n) = sum_{j=0}^{10} (-n)^j
Set S <- 0
For k from 1 to 10:
Set points <- [(i, u(i)) for i = 1, ..., k]
Set FIT_k <- LAGRANGE_EVAL(points, k + 1)
Set S <- S + FIT_k
Return S
Set k <- |points|
Set result <- 0
For i from 1 to k:
(x_i, y_i) <- points[i]
Set basis <- y_i
For j from 1 to k, j != i:
(x_j, _) <- points[j]
Set basis <- basis * (x0 - x_j) / (x_i - x_j)
Set result <- result + basis
Return result
Complexity Analysis
- Time. For each , the Lagrange evaluation costs operations. The total is arithmetic operations. In general, for a degree- generating function, the cost is .
- Space. for storing the data points and intermediate computations.
Answer
Code
Each problem page includes the exact C++ and Python source files from the local archive.
#include <iostream>
#include <vector>
#include <numeric>
#include <cassert>
using namespace std;
/*
* Problem 101: Optimum Polynomial
*
* u(n) = sum_{j=0}^{10} (-1)^j n^j.
* For k = 1..10, interpolate the first k values and evaluate at k+1.
* Sum the resulting FITs.
*
* Uses exact rational Lagrange interpolation via long long numerator/denominator.
*/
long long u(long long n) {
long long result = 0, pw = 1;
for (int j = 0; j <= 10; j++) {
result += (j % 2 == 0 ? pw : -pw);
pw *= n;
}
return result;
}
long long gcd_abs(long long a, long long b) {
a = abs(a); b = abs(b);
while (b) { a %= b; swap(a, b); }
return a;
}
struct Frac {
long long num, den;
Frac(long long n = 0, long long d = 1) : num(n), den(d) { reduce(); }
void reduce() {
if (den < 0) { num = -num; den = -den; }
long long g = gcd_abs(num, den);
if (g > 0) { num /= g; den /= g; }
}
Frac operator*(const Frac& o) const { return Frac(num * o.num, den * o.den); }
Frac operator+(const Frac& o) const {
return Frac(num * o.den + o.num * den, den * o.den);
}
};
int main() {
vector<long long> vals(12);
for (int n = 1; n <= 11; n++) vals[n] = u(n);
long long total = 0;
for (int k = 1; k <= 10; k++) {
long long target = k + 1;
Frac result(0, 1);
for (int i = 1; i <= k; i++) {
Frac term(vals[i], 1);
for (int j = 1; j <= k; j++) {
if (j == i) continue;
term = term * Frac(target - j, i - j);
}
result = result + term;
}
assert(result.den == 1);
total += result.num;
}
cout << total << endl;
assert(total == 37076114526LL);
return 0;
}
"""
Problem 101: Optimum Polynomial
Given u(n) = sum_{j=0}^{10} (-1)^j n^j, find the sum of all FITs
for the BOPs using the first k = 1, ..., 10 terms.
"""
from fractions import Fraction
def u(n):
return sum((-n) ** j for j in range(11))
def lagrange_eval(points, x):
k = len(points)
result = Fraction(0)
for i in range(k):
xi, yi = points[i]
term = Fraction(yi)
for j in range(k):
if j != i:
xj = points[j][0]
term *= Fraction(x - xj, xi - xj)
result += term
return result
def solve():
total = 0
for k in range(1, 11):
points = [(i, u(i)) for i in range(1, k + 1)]
fit = lagrange_eval(points, k + 1)
total += int(fit)
return total
if __name__ == "__main__":
answer = solve()
print(answer)
assert answer == 37076114526