This documentation is automatically generated by online-judge-tools/verification-helper
#include "math/combinatorics/lagrange-polynomial-3.hpp"
/**
* @brief Lagrange Polynomial(多項式補間, 値)
*/
template< typename Mint, typename F >
vector< Mint > lagrange_polynomial(const vector< Mint > &y, int64_t T, const int &m, const F &multiply) {
int k = (int) y.size() - 1;
T %= Mint::mod();
if(T <= k) {
vector< Mint > ret(m);
int ptr = 0;
for(int64_t i = T; i <= k and ptr < m; i++) {
ret[ptr++] = y[i];
}
if(k + 1 < T + m) {
auto suf = lagrange_polynomial(y, k + 1, m - ptr, multiply);
for(int i = k + 1; i < T + m; i++) {
ret[ptr++] = suf[i - (k + 1)];
}
}
return ret;
}
if(T + m > Mint::mod()) {
auto pref = lagrange_polynomial(y, T, Mint::mod() - T, multiply);
auto suf = lagrange_polynomial(y, 0, m - pref.size(), multiply);
copy(begin(suf), end(suf), back_inserter(pref));
return pref;
}
vector< Mint > finv(k + 1, 1), d(k + 1);
for(int i = 2; i <= k; i++) finv[k] *= i;
finv[k] = Mint(1) / finv[k];
for(int i = k; i >= 1; i--) finv[i - 1] = finv[i] * i;
for(int i = 0; i <= k; i++) {
d[i] = finv[i] * finv[k - i] * y[i];
if((k - i) & 1) d[i] = -d[i];
}
vector< Mint > h(m + k);
for(int i = 0; i < m + k; i++) {
h[i] = Mint(1) / (T - k + i);
}
auto dh = multiply(d, h);
vector< Mint > ret(m);
Mint cur = T;
for(int i = 1; i <= k; i++) cur *= T - i;
for(int i = 0; i < m; i++) {
ret[i] = cur * dh[k + i];
cur *= T + i + 1;
cur *= h[i];
}
return ret;
}
#line 1 "math/combinatorics/lagrange-polynomial-3.hpp"
/**
* @brief Lagrange Polynomial(多項式補間, 値)
*/
template< typename Mint, typename F >
vector< Mint > lagrange_polynomial(const vector< Mint > &y, int64_t T, const int &m, const F &multiply) {
int k = (int) y.size() - 1;
T %= Mint::mod();
if(T <= k) {
vector< Mint > ret(m);
int ptr = 0;
for(int64_t i = T; i <= k and ptr < m; i++) {
ret[ptr++] = y[i];
}
if(k + 1 < T + m) {
auto suf = lagrange_polynomial(y, k + 1, m - ptr, multiply);
for(int i = k + 1; i < T + m; i++) {
ret[ptr++] = suf[i - (k + 1)];
}
}
return ret;
}
if(T + m > Mint::mod()) {
auto pref = lagrange_polynomial(y, T, Mint::mod() - T, multiply);
auto suf = lagrange_polynomial(y, 0, m - pref.size(), multiply);
copy(begin(suf), end(suf), back_inserter(pref));
return pref;
}
vector< Mint > finv(k + 1, 1), d(k + 1);
for(int i = 2; i <= k; i++) finv[k] *= i;
finv[k] = Mint(1) / finv[k];
for(int i = k; i >= 1; i--) finv[i - 1] = finv[i] * i;
for(int i = 0; i <= k; i++) {
d[i] = finv[i] * finv[k - i] * y[i];
if((k - i) & 1) d[i] = -d[i];
}
vector< Mint > h(m + k);
for(int i = 0; i < m + k; i++) {
h[i] = Mint(1) / (T - k + i);
}
auto dh = multiply(d, h);
vector< Mint > ret(m);
Mint cur = T;
for(int i = 1; i <= k; i++) cur *= T - i;
for(int i = 0; i < m; i++) {
ret[i] = cur * dh[k + i];
cur *= T + i + 1;
cur *= h[i];
}
return ret;
}