This documentation is automatically generated by online-judge-tools/verification-helper
View the Project on GitHub tko919/library
#include "FPS/arbitraryfps.hpp"
#pragma once template <typename T> struct Poly : vector<T> { Poly(int n = 0) { this->assign(n, T()); } Poly(const initializer_list<T> f) : vector<T>::vector(f) {} Poly(const vector<T> &f) { this->assign(ALL(f)); } int deg() const { return this->size() - 1; } T eval(const T &x) { T res; for (int i = this->size() - 1; i >= 0; i--) res *= x, res += this->at(i); return res; } Poly rev() const { Poly res = *this; reverse(ALL(res)); return res; } void shrink() { while (!this->empty() and this->back() == 0) this->pop_back(); } Poly operator>>(ll sz) const { if ((int)this->size() <= sz) return {}; Poly ret(*this); ret.erase(ret.begin(), ret.begin() + sz); return ret; } Poly operator<<(ll sz) const { Poly ret(*this); ret.insert(ret.begin(), sz, T(0)); return ret; } Poly inv() const { assert(this->front() != 0); const int n = this->size(); Poly res(1); res.front() = T(1) / this->front(); for (int k = 1; k < n; k <<= 1) { Poly g = res, h = *this; h.resize(k * 2); res.resize(k * 2); g = (g.square() * h); g.resize(k * 2); rep(i, k, min(k * 2, n)) res[i] -= g[i]; } res.resize(n); return res; } Poly square() const { return Poly(mult(*this, *this)); } Poly operator-() const { return Poly() - *this; } Poly operator+(const Poly &g) const { return Poly(*this) += g; } Poly operator+(const T &g) const { return Poly(*this) += g; } Poly operator-(const Poly &g) const { return Poly(*this) -= g; } Poly operator-(const T &g) const { return Poly(*this) -= g; } Poly operator*(const Poly &g) const { return Poly(*this) *= g; } Poly operator*(const T &g) const { return Poly(*this) *= g; } Poly operator/(const Poly &g) const { return Poly(*this) /= g; } Poly operator%(const Poly &g) const { return Poly(*this) %= g; } pair<Poly, Poly> divmod(const Poly &g) const { Poly q = *this / g, r = *this - g * q; r.shrink(); return {q, r}; } Poly &operator+=(const Poly &g) { if (g.size() > this->size()) this->resize(g.size()); rep(i, 0, g.size()) { (*this)[i] += g[i]; } return *this; } Poly &operator+=(const T &g) { if (this->empty()) this->push_back(0); (*this)[0] += g; return *this; } Poly &operator-=(const Poly &g) { if (g.size() > this->size()) this->resize(g.size()); rep(i, 0, g.size()) { (*this)[i] -= g[i]; } return *this; } Poly &operator-=(const T &g) { if (this->empty()) this->push_back(0); (*this)[0] -= g; return *this; } Poly &operator*=(const Poly &g) { *this = mult(*this, g); return *this; } Poly &operator*=(const T &g) { rep(i, 0, this->size())(*this)[i] *= g; return *this; } Poly &operator/=(const Poly &g) { if (g.size() > this->size()) { this->clear(); return *this; } Poly g2 = g; reverse(ALL(*this)); reverse(ALL(g2)); int n = this->size() - g2.size() + 1; this->resize(n); g2.resize(n); *this *= g2.inv(); this->resize(n); reverse(ALL(*this)); shrink(); return *this; } Poly &operator%=(const Poly &g) { *this -= *this / g * g; shrink(); return *this; } Poly diff() const { Poly res(this->size() - 1); rep(i, 0, res.size()) res[i] = (*this)[i + 1] * (i + 1); return res; } Poly inte() const { Poly res(this->size() + 1); for (int i = res.size() - 1; i; i--) res[i] = (*this)[i - 1] / i; return res; } Poly log() const { assert(this->front() == 1); const int n = this->size(); Poly res = diff() * inv(); res = res.inte(); res.resize(n); return res; } Poly exp() const { assert(this->front() == 0); const int n = this->size(); Poly res(1), g(1); res.front() = g.front() = 1; for (int k = 1; k < n; k <<= 1) { g = (g + g - g.square() * res); g.resize(k); Poly q = *this; q.resize(k); q = q.diff(); Poly w = (q + g * (res.diff() - res * q)), t = *this; w.resize(k * 2 - 1); t.resize(k * 2); res = (res + res * (t - w.inte())); res.resize(k * 2); } res.resize(n); return res; } Poly shift(const int &c) const { const int n = this->size(); Poly res = *this, g(n); g[0] = 1; rep(i, 1, n) g[i] = g[i - 1] * c / i; vector<T> fact(n, 1); rep(i, 0, n) { if (i) fact[i] = fact[i - 1] * i; res[i] *= fact[i]; } res = res.rev(); res *= g; res.resize(n); res = res.rev(); rep(i, 0, n) res[i] /= fact[i]; return res; } Poly pow(ll t) { if (t == 0) { Poly res(this->size()); res[0] = 1; return res; } int n = this->size(), k = 0; while (k < n and (*this)[k] == 0) k++; Poly res(n); if (__int128_t(t) * k >= n) return res; n -= t * k; Poly g(n); T c = (*this)[k], ic = c.inv(); rep(i, 0, n) g[i] = (*this)[i + k] * ic; g = g.log(); for (auto &x : g) x *= t; g = g.exp(); c = c.pow(t); rep(i, 0, n) res[i + t * k] = g[i] * c; return res; } vector<T> mult(const vector<T> &a, const vector<T> &b) const; }; /** * @brief Formal Power Series (Arbitrary mod) */
#line 2 "FPS/arbitraryfps.hpp" template <typename T> struct Poly : vector<T> { Poly(int n = 0) { this->assign(n, T()); } Poly(const initializer_list<T> f) : vector<T>::vector(f) {} Poly(const vector<T> &f) { this->assign(ALL(f)); } int deg() const { return this->size() - 1; } T eval(const T &x) { T res; for (int i = this->size() - 1; i >= 0; i--) res *= x, res += this->at(i); return res; } Poly rev() const { Poly res = *this; reverse(ALL(res)); return res; } void shrink() { while (!this->empty() and this->back() == 0) this->pop_back(); } Poly operator>>(ll sz) const { if ((int)this->size() <= sz) return {}; Poly ret(*this); ret.erase(ret.begin(), ret.begin() + sz); return ret; } Poly operator<<(ll sz) const { Poly ret(*this); ret.insert(ret.begin(), sz, T(0)); return ret; } Poly inv() const { assert(this->front() != 0); const int n = this->size(); Poly res(1); res.front() = T(1) / this->front(); for (int k = 1; k < n; k <<= 1) { Poly g = res, h = *this; h.resize(k * 2); res.resize(k * 2); g = (g.square() * h); g.resize(k * 2); rep(i, k, min(k * 2, n)) res[i] -= g[i]; } res.resize(n); return res; } Poly square() const { return Poly(mult(*this, *this)); } Poly operator-() const { return Poly() - *this; } Poly operator+(const Poly &g) const { return Poly(*this) += g; } Poly operator+(const T &g) const { return Poly(*this) += g; } Poly operator-(const Poly &g) const { return Poly(*this) -= g; } Poly operator-(const T &g) const { return Poly(*this) -= g; } Poly operator*(const Poly &g) const { return Poly(*this) *= g; } Poly operator*(const T &g) const { return Poly(*this) *= g; } Poly operator/(const Poly &g) const { return Poly(*this) /= g; } Poly operator%(const Poly &g) const { return Poly(*this) %= g; } pair<Poly, Poly> divmod(const Poly &g) const { Poly q = *this / g, r = *this - g * q; r.shrink(); return {q, r}; } Poly &operator+=(const Poly &g) { if (g.size() > this->size()) this->resize(g.size()); rep(i, 0, g.size()) { (*this)[i] += g[i]; } return *this; } Poly &operator+=(const T &g) { if (this->empty()) this->push_back(0); (*this)[0] += g; return *this; } Poly &operator-=(const Poly &g) { if (g.size() > this->size()) this->resize(g.size()); rep(i, 0, g.size()) { (*this)[i] -= g[i]; } return *this; } Poly &operator-=(const T &g) { if (this->empty()) this->push_back(0); (*this)[0] -= g; return *this; } Poly &operator*=(const Poly &g) { *this = mult(*this, g); return *this; } Poly &operator*=(const T &g) { rep(i, 0, this->size())(*this)[i] *= g; return *this; } Poly &operator/=(const Poly &g) { if (g.size() > this->size()) { this->clear(); return *this; } Poly g2 = g; reverse(ALL(*this)); reverse(ALL(g2)); int n = this->size() - g2.size() + 1; this->resize(n); g2.resize(n); *this *= g2.inv(); this->resize(n); reverse(ALL(*this)); shrink(); return *this; } Poly &operator%=(const Poly &g) { *this -= *this / g * g; shrink(); return *this; } Poly diff() const { Poly res(this->size() - 1); rep(i, 0, res.size()) res[i] = (*this)[i + 1] * (i + 1); return res; } Poly inte() const { Poly res(this->size() + 1); for (int i = res.size() - 1; i; i--) res[i] = (*this)[i - 1] / i; return res; } Poly log() const { assert(this->front() == 1); const int n = this->size(); Poly res = diff() * inv(); res = res.inte(); res.resize(n); return res; } Poly exp() const { assert(this->front() == 0); const int n = this->size(); Poly res(1), g(1); res.front() = g.front() = 1; for (int k = 1; k < n; k <<= 1) { g = (g + g - g.square() * res); g.resize(k); Poly q = *this; q.resize(k); q = q.diff(); Poly w = (q + g * (res.diff() - res * q)), t = *this; w.resize(k * 2 - 1); t.resize(k * 2); res = (res + res * (t - w.inte())); res.resize(k * 2); } res.resize(n); return res; } Poly shift(const int &c) const { const int n = this->size(); Poly res = *this, g(n); g[0] = 1; rep(i, 1, n) g[i] = g[i - 1] * c / i; vector<T> fact(n, 1); rep(i, 0, n) { if (i) fact[i] = fact[i - 1] * i; res[i] *= fact[i]; } res = res.rev(); res *= g; res.resize(n); res = res.rev(); rep(i, 0, n) res[i] /= fact[i]; return res; } Poly pow(ll t) { if (t == 0) { Poly res(this->size()); res[0] = 1; return res; } int n = this->size(), k = 0; while (k < n and (*this)[k] == 0) k++; Poly res(n); if (__int128_t(t) * k >= n) return res; n -= t * k; Poly g(n); T c = (*this)[k], ic = c.inv(); rep(i, 0, n) g[i] = (*this)[i + k] * ic; g = g.log(); for (auto &x : g) x *= t; g = g.exp(); c = c.pow(t); rep(i, 0, n) res[i + t * k] = g[i] * c; return res; } vector<T> mult(const vector<T> &a, const vector<T> &b) const; }; /** * @brief Formal Power Series (Arbitrary mod) */