結果
問題 | No.1559 Next Rational |
ユーザー |
|
提出日時 | 2021-06-26 00:40:10 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 3 ms / 2,000 ms |
コード長 | 34,111 bytes |
コンパイル時間 | 3,742 ms |
コンパイル使用メモリ | 240,848 KB |
最終ジャッジ日時 | 2025-01-22 12:56:01 |
ジャッジサーバーID (参考情報) |
judge5 / judge5 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 15 |
ソースコード
#include <bits/stdc++.h>#pragma region Headerusing i32 = int;using u32 = unsigned int;using i64 = long long;using u64 = unsigned long long;using i128 = __int128_t;using u128 = __uint128_t;using f64 = double;using f80 = long double;using f128 = __float128;constexpr i32 operator"" _i32(u64 v){return v;}constexpr i32 operator"" _u32(u64 v){return v;}constexpr i64 operator"" _i64(u64 v){return v;}constexpr u64 operator"" _u64(u64 v){return v;}constexpr f64 operator"" _f64(f80 v){return v;}constexpr f80 operator"" _f80(f80 v){return v;}using Istream = std::istream;using Ostream = std::ostream;using Str = std::string;template<typename T>using Lt = std::less<T>;template<typename T>using Gt = std::greater<T>;template<typename T>using IList = std::initializer_list<T>;template<int n>using BSet = std::bitset<n>;template<typename T1, typename T2>using Pair = std::pair<T1, T2>;template<typename... Ts>using Tup = std::tuple<Ts...>;template<typename T, int N>using Arr = std::array<T, N>;template<typename... Ts>using Deq = std::deque<Ts...>;template<typename... Ts>using Set = std::set<Ts...>;template<typename... Ts>using MSet = std::multiset<Ts...>;template<typename... Ts>using USet = std::unordered_set<Ts...>;template<typename... Ts>using UMSet = std::unordered_multiset<Ts...>;template<typename... Ts>using Map = std::map<Ts...>;template<typename... Ts>using MMap = std::multimap<Ts...>;template<typename... Ts>using UMap = std::unordered_map<Ts...>;template<typename... Ts>using UMMap = std::unordered_multimap<Ts...>;template<typename... Ts>using Vec = std::vector<Ts...>;template<typename... Ts>using Stack = std::stack<Ts...>;template<typename... Ts>using Queue = std::queue<Ts...>;template<typename T>using MaxHeap = std::priority_queue<T>;template<typename T>using MinHeap = std::priority_queue<T, Vec<T>, Gt<T>>;using NSec = std::chrono::nanoseconds;using USec = std::chrono::microseconds;using MSec = std::chrono::milliseconds;using Sec = std::chrono::seconds;template<typename T>constexpr T LIMMIN = std::numeric_limits<T>::min();template<typename T>constexpr T LIMMAX = std::numeric_limits<T>::max();template<typename T>constexpr T INF = (LIMMAX<T> - 1) / 2;template<typename T>constexpr T PI = T{3.141592653589793238462643383279502884};template<typename T = u64>constexpr T TEN(const int n){return n == 0 ? T{1} : TEN<T>(n - 1) * T{10};}Ostream& operator<<(Ostream& os, i128 v){bool minus = false;if (v < 0) { minus = true, v = -v; }Str ans;if (v == 0) { ans = "0"; }while (v) {ans.push_back('0' + v % 10), v /= 10;}std::reverse(ans.begin(), ans.end());return os << (minus ? "-" : "") << ans;}Ostream& operator<<(Ostream& os, u128 v){Str ans;if (v == 0) { ans = "0"; }while (v) {ans.push_back('0' + v % 10), v /= 10;}std::reverse(ans.begin(), ans.end());return os << ans;}template<typename T>bool chmin(T& a, const T& b){if (a > b) {a = b;return true;} else {return false;}}template<typename T>bool chmax(T& a, const T& b){if (a < b) {a = b;return true;} else {return false;}}template<typename T>constexpr T fdiv(T x, T y){if (y < T{}) { x = -x, y = -y; }return x >= T{} ? x / y : (x - y + 1) / y;}template<typename T>constexpr T cdiv(T x, T y){if (y < T{}) { x = -x, y = -y; }return x >= T{} ? (x + y - 1) / y : x / y;}template<typename T, typename I>constexpr T modPower(T v, I n, T mod){T ans = 1 % mod;for (; n > 0; n >>= 1, (v *= v) %= mod) {if (n % 2 == 1) { (ans *= v) %= mod; }}return ans;}template<typename T, typename I>constexpr T power(T v, I n){T ans = 1;for (; n > 0; n >>= 1, v *= v) {if (n % 2 == 1) { ans *= v; }}return ans;}template<typename T, typename I>constexpr T power(T v, I n, const T& e){T ans = e;for (; n > 0; n >>= 1, v *= v) {if (n % 2 == 1) { ans *= v; }}return ans;}template<typename T>Vec<T> operator+=(Vec<T>& vs1, const Vec<T>& vs2){vs1.insert(vs1.end(), vs2.begin(), vs2.end());return vs1;}template<typename T>Vec<T> operator+(const Vec<T>& vs1, const Vec<T>& vs2){auto vs = vs1;vs += vs2;return vs;}template<typename T>void fillAll(Vec<T>& vs, const T& v){std::fill(vs.begin(), vs.end(), v);}template<typename T, typename C = Lt<T>>void sortAll(Vec<T>& vs, C comp = C{}){std::sort(vs.begin(), vs.end(), comp);}template<typename T>void reverseAll(Vec<T>& vs){std::reverse(vs.begin(), vs.end());}template<typename T>void uniqueAll(Vec<T>& vs){sortAll(vs);vs.erase(std::unique(vs.begin(), vs.end()), vs.end());}template<typename T, typename V = T>V sumAll(const Vec<T>& vs){return std::accumulate(vs.begin(), vs.end(), V{});}template<typename T>int minInd(const Vec<T>& vs){return std::min_element(vs.begin(), vs.end()) - vs.begin();}template<typename T>int maxInd(const Vec<T>& vs){return std::max_element(vs.begin(), vs.end()) - vs.begin();}template<typename T>int lbInd(const Vec<T>& vs, const T& v){return std::lower_bound(vs.begin(), vs.end(), v) - vs.begin();}template<typename T>int ubInd(const Vec<T>& vs, const T& v){return std::upper_bound(vs.begin(), vs.end(), v) - vs.begin();}template<typename T, typename F>Vec<T> genVec(int n, F gen){Vec<T> ans;std::generate_n(std::back_insert_iterator(ans), n, gen);return ans;}Vec<int> iotaVec(int n, int offset = 0){Vec<int> ans(n);std::iota(ans.begin(), ans.end(), offset);return ans;}template<typename T>Vec<T> revVec(const Vec<T>& vs){auto ans = vs;reverseAll(ans);return ans;}constexpr int popcount(const u64 v){return v ? __builtin_popcountll(v) : 0;}constexpr int log2p1(const u64 v){return v ? 64 - __builtin_clzll(v) : 0;}constexpr int lsbp1(const u64 v){return __builtin_ffsll(v);}constexpr int clog(const u64 v){return v ? log2p1(v - 1) : 0;}constexpr u64 ceil2(const u64 v){const int l = clog(v);return (l == 64) ? 0_u64 : (1_u64 << l);}constexpr u64 floor2(const u64 v){return v ? (1_u64 << (log2p1(v) - 1)) : 0_u64;}constexpr bool ispow2(const u64 v){return (v > 0) and ((v & (v - 1)) == 0);}constexpr bool btest(const u64 mask, const int ind){return (mask >> ind) & 1_u64;}template<typename F>struct Fix : F{Fix(F&& f) : F{std::forward<F>(f)} {}template<typename... Args>auto operator()(Args&&... args) const{return F::operator()(*this, std::forward<Args>(args)...);}};class irange{private:struct itr{itr(i64 start = 0, i64 step = 1) : m_cnt{start}, m_step{step} {}bool operator!=(const itr& it) const{return m_cnt != it.m_cnt;}int operator*(){return m_cnt;}itr& operator++(){m_cnt += m_step;return *this;}i64 m_cnt, m_step;};i64 m_start, m_end, m_step;public:irange(i64 start, i64 end, i64 step = 1){assert(step != 0);const i64 d = std::abs(step);const i64 l = (step > 0 ? start : end);const i64 r = (step > 0 ? end : start);int n = (r - l) / d + ((r - l) % d ? 1 : 0);if (l >= r) { n = 0; }m_start = start;m_end = start + step * n;m_step = step;}itr begin() const{return itr{m_start, m_step};}itr end() const{return itr{m_end, m_step};}};irange rep(int end){return irange(0, end, 1);}irange per(int rend){return irange(rend - 1, -1, -1);}#pragma COMMENT("[REFS] Xoshiro: https://prng.di.unimi.it")namespace xoshiro_impl {u64 x;u64 next(){uint64_t z = (x += 0x9e3779b97f4a7c15);z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;z = (z ^ (z >> 27)) * 0x94d049bb133111eb;return z ^ (z >> 31);}}class Xoshiro32{public:using result_type = u32;using T = result_type;Xoshiro32(T seed = 0){xoshiro_impl::x = seed;s[0] = xoshiro_impl::next();s[1] = xoshiro_impl::next();s[2] = xoshiro_impl::next();s[3] = xoshiro_impl::next();}static constexpr T min(){return LIMMIN<T>;}static constexpr T max(){return LIMMAX<T>;}T operator()(){return next();}private:static constexpr T rotl(const T x, int k){return (x << k) | (x >> (32 - k));}T next(){const T ans = rotl(s[1] * 5, 7) * 9;const T t = s[1] << 9;s[2] ^= s[0];s[3] ^= s[1];s[1] ^= s[2];s[0] ^= s[3];s[2] ^= t;s[3] = rotl(s[3], 11);return ans;}T s[4];};class Xoshiro64{public:using result_type = u64;using T = result_type;Xoshiro64(T seed = 0){xoshiro_impl::x = seed;s[0] = xoshiro_impl::next();s[1] = xoshiro_impl::next();s[2] = xoshiro_impl::next();s[3] = xoshiro_impl::next();}static constexpr T min(){return LIMMIN<T>;}static constexpr T max(){return LIMMAX<T>;}T operator()(){return next();}private:static constexpr T rotl(const T x, int k){return (x << k) | (x >> (64 - k));}T next(){const T ans = rotl(s[1] * 5, 7) * 9;const T t = s[1] << 17;s[2] ^= s[0];s[3] ^= s[1];s[1] ^= s[2];s[0] ^= s[3];s[2] ^= t;s[3] = rotl(s[3], 45);return ans;}T s[4];};template<typename Rng>class RNG{public:using result_type = typename Rng::result_type;using T = result_type;static constexpr T min(){return Rng::min();}static constexpr T max(){return Rng::max();}RNG() : RNG(std::random_device{}()) {}RNG(T seed) : m_rng(seed) {}T operator()(){return m_rng();}template<typename T>T val(T min, T max){return std::uniform_int_distribution<T>(min, max)(m_rng);}template<typename T>Pair<T, T> pair(T min, T max){return std::minmax({val<T>(min, max), val<T>(min, max)});}template<typename T>Vec<T> vec(int n, T min, T max){return genVec<T>(n, [&]() { return val<T>(min, max); });}template<typename T>Vec<Vec<T>> vvec(int n, int m, T min, T max){return genVec<Vec<T>>(n, [&]() { return vec(m, min, max); });}private:Rng m_rng;};RNG<std::mt19937> rng;RNG<std::mt19937_64> rng64;RNG<Xoshiro32> rng_xo;RNG<Xoshiro64> rng_xo64;class Scanner{public:Scanner(Istream& is = std::cin) : m_is{is}{m_is.tie(nullptr)->sync_with_stdio(false);}template<typename T>T val(){T v;return m_is >> v, v;}template<typename T>T val(T offset){return val<T>() - offset;}template<typename T>Vec<T> vec(int n){return genVec<T>(n, [&]() { return val<T>(); });}template<typename T>Vec<T> vec(int n, T offset){return genVec<T>(n, [&]() { return val<T>(offset); });}template<typename T>Vec<Vec<T>> vvec(int n, int m){return genVec<Vec<T>>(n, [&]() { return vec<T>(m); });}template<typename T>Vec<Vec<T>> vvec(int n, int m, const T offset){return genVec<Vec<T>>(n, [&]() { return vec<T>(m, offset); });}template<typename... Args>auto tup(){return Tup<Args...>{val<Args>()...};}template<typename... Args>auto tup(const Args&... offsets){return Tup<Args...>{val<Args>(offsets)...};}private:Istream& m_is;};Scanner in;class Printer{public:Printer(Ostream& os = std::cout) : m_os{os}{m_os << std::fixed << std::setprecision(15);}template<typename... Args>int operator()(const Args&... args){dump(args...);return 0;}template<typename... Args>int ln(const Args&... args){dump(args...), m_os << '\n';return 0;}template<typename... Args>int el(const Args&... args){dump(args...), m_os << std::endl;return 0;}private:template<typename T>void dump(const T& v){m_os << v;}template<typename T>void dump(const Vec<T>& vs){for (const int i : rep(vs.size())) {m_os << (i ? " " : ""), dump(vs[i]);}}template<typename T>void dump(const Vec<Vec<T>>& vss){for (const int i : rep(vss.size())) {m_os << (i ? "\n" : ""), dump(vss[i]);}}template<typename T, typename... Ts>int dump(const T& v, const Ts&... args){dump(v), m_os << ' ', dump(args...);return 0;}Ostream& m_os;};Printer out;template<typename T, int n, int i = 0>auto ndVec(int const (&szs)[n], const T x = T{}){if constexpr (i == n) {return x;} else {return std::vector(szs[i], ndVec<T, n, i + 1>(szs, x));}}template<typename T, typename F>T binSearch(T ng, T ok, F check){while (std::abs(ok - ng) > 1) {const T mid = (ok + ng) / 2;(check(mid) ? ok : ng) = mid;}return ok;}template<u32 mod_, u32 root_, u32 max2p_>class modint{template<typename U = u32&>static U modRef(){static u32 s_mod = 0;return s_mod;}template<typename U = u32&>static U rootRef(){static u32 s_root = 0;return s_root;}template<typename U = u32&>static U max2pRef(){static u32 s_max2p = 0;return s_max2p;}public:template<typename U = const u32>static constexpr std::enable_if_t<mod_ != 0, U> mod(){return mod_;}template<typename U = const u32>static std::enable_if_t<mod_ == 0, U> mod(){return modRef();}template<typename U = const u32>static constexpr std::enable_if_t<mod_ != 0, U> root(){return root_;}template<typename U = const u32>static std::enable_if_t<mod_ == 0, U> root(){return rootRef();}template<typename U = const u32>static constexpr std::enable_if_t<mod_ != 0, U> max2p(){return max2p_;}template<typename U = const u32>static std::enable_if_t<mod_ == 0, U> max2p(){return max2pRef();}template<typename U = u32>static void setMod(std::enable_if_t<mod_ == 0, U> m){modRef() = m;}template<typename U = u32>static void setRoot(std::enable_if_t<mod_ == 0, U> r){rootRef() = r;}template<typename U = u32>static void setMax2p(std::enable_if_t<mod_ == 0, U> m){max2pRef() = m;}constexpr modint() : m_val{0} {}constexpr modint(i64 v) : m_val{normll(v)} {}constexpr void setRaw(u32 v){m_val = v;}constexpr modint operator-() const{return modint{0} - (*this);}constexpr modint& operator+=(const modint& m){m_val = norm(m_val + m.val());return *this;}constexpr modint& operator-=(const modint& m){m_val = norm(m_val + mod() - m.val());return *this;}constexpr modint& operator*=(const modint& m){m_val = normll((i64)m_val * (i64)m.val() % (i64)mod());return *this;}constexpr modint& operator/=(const modint& m){return *this *= m.inv();}constexpr modint operator+(const modint& m) const{auto v = *this;return v += m;}constexpr modint operator-(const modint& m) const{auto v = *this;return v -= m;}constexpr modint operator*(const modint& m) const{auto v = *this;return v *= m;}constexpr modint operator/(const modint& m) const{auto v = *this;return v /= m;}constexpr bool operator==(const modint& m) const{return m_val == m.val();}constexpr bool operator!=(const modint& m) const{return not(*this == m);}friend Istream& operator>>(Istream& is, modint& m){i64 v;return is >> v, m = v, is;}friend Ostream& operator<<(Ostream& os, const modint& m){return os << m.val();}constexpr u32 val() const{return m_val;}template<typename I>constexpr modint pow(I n) const{return power(*this, n);}constexpr modint inv() const{return pow(mod() - 2);}static modint sinv(u32 n){static Vec<modint> is{1, 1};for (u32 i = (u32)is.size(); i <= n; i++) {is.push_back(-is[mod() % i] * (mod() / i));}return is[n];}static modint fact(u32 n){static Vec<modint> fs{1, 1};for (u32 i = (u32)fs.size(); i <= n; i++) {fs.push_back(fs.back() * i);}return fs[n];}static modint ifact(u32 n){static Vec<modint> ifs{1, 1};for (u32 i = (u32)ifs.size(); i <= n; i++) {ifs.push_back(ifs.back() * sinv(i));}return ifs[n];}static modint comb(int n, int k){return k > n or k < 0 ? modint{0} : fact(n) * ifact(n - k) * ifact(k);}private:static constexpr u32 norm(u32 x){return x < mod() ? x : x - mod();}static constexpr u32 normll(i64 x){return norm(u32(x % (i64)mod() + (i64)mod()));}u32 m_val;};using modint_1000000007 = modint<1000000007, 5, 1>;using modint_998244353 = modint<998244353, 3, 23>;template<int id>using modint_dynamic = modint<0, 0, id>;template<typename T>Vec<T> berlekampMassey(const Vec<T>& A){const int N = (int)A.size();Vec<T> B{1}, C{1};T b = 1;for (int j : irange(1, N + 1)) {int m = (int)B.size(), l = (int)C.size();T d = 0;for (int i : rep(l)) {d += A[j - l + i] * C[i];}B.push_back(0), m++;if (d == 0) { continue; }const T c = -d / b;if (l < m) {auto temp = C;C.insert(C.begin(), m - l, 0);for (int i : rep(m)) {C[m - 1 - i] += c * B[m - 1 - i];}B = temp, b = d;} else {for (int i : rep(m)) {C[l - 1 - i] += c * B[m - 1 - i];}}}reverseAll(C);return C;}template<typename mint>class FPS : public Vec<mint>{public:using std::vector<mint>::vector;using std::vector<mint>::resize;FPS(const Vec<mint>& vs) : Vec<mint>{vs} {}int size() const{return Vec<mint>::size();}int deg() const{return size() - 1;}FPS low(int n) const{return FPS{this->begin(), this->begin() + std::min(n, size())};}FPS rev() const{FPS ans = *this;reverseAll(ans);return ans;}mint eval(const mint& x) const{mint ans = 0;mint power = 1;for (int i : rep(size())) {ans += power * (*this)[i];power *= x;}return ans;}mint& operator[](const int n){if (deg() < n) { resize(n + 1); }return Vec<mint>::operator[](n);}const mint& operator[](const int n) const{return Vec<mint>::operator[](n);}template<typename I>mint at(const I n) const{return (n < size() ? (*this)[n] : mint{0});}FPS operator-() const{FPS ans = *this;for (auto& v : ans) {v = -v;}return ans;}FPS& operator+=(const FPS& f){for (int i : rep(f.size())) {(*this)[i] += f[i];}return *this;}FPS& operator-=(const FPS& f){for (int i : rep(f.size())) {(*this)[i] -= f[i];}return *this;}FPS& operator*=(const FPS& f){return (*this) = (*this) * f;}FPS& operator<<=(const int s){return *this = (*this << s);}FPS& operator>>=(const int s){return *this = (*this >> s);}FPS operator+(const FPS& f) const{return FPS(*this) += f;}FPS operator-(const FPS& f) const{return FPS(*this) -= f;}FPS operator*(const FPS& f) const{return mult(f, size() + f.size() - 1);}FPS operator<<(const int s) const{FPS ans(size() + s);for (int i : rep(size())) {ans[i + s] = (*this)[i];}return ans;}FPS operator>>(const int s) const{FPS ans;for (int i : irange(s, size())) {ans[i - s] = (*this)[i];}return ans;}friend Ostream& operator<<(Ostream& os, const FPS& f){return os << static_cast<Vec<mint>>(f);}FPS derivative() const{FPS ans;for (int i : irange(1, size())) {ans[i - 1] = (*this)[i] * i;}return ans;}FPS integral() const{FPS ans;for (int i : irange(1, size() + 1)) {ans[i] = (*this)[i - 1] * mint::sinv(i);}return ans;}FPS mult(const FPS& f, int sz) const{if (sz == 0) { return FPS{}; }const int N = std::min(size(), sz) + std::min(f.size(), sz) - 1;if (N < 10) {FPS ans;for (int i : rep(sz)) {for (int j : rep(sz)) {if (i + j >= sz) { break; }ans[i + j] += this->at(i) * f.at(j);}}return ans;}if (N <= (1 << mint::max2p())) {auto ans = conv<mint>(*this, f, sz);return ans;} else {const auto cs1 = conv<submint1>(*this, f, sz);const auto cs2 = conv<submint2>(*this, f, sz);const auto cs3 = conv<submint3>(*this, f, sz);FPS ans((int)cs1.size());for (int i : rep(cs1.size())) {ans[i] = restore(cs1[i].val(), cs2[i].val(), cs3[i].val());}return ans;}}FPS smult(int p, const mint a, int sz){FPS ans = low(sz);for (int i = 0; i + p < sz; i++) {ans[i + p] += (*this)[i] * a;}return ans;}FPS sdiv(int p, const mint& a, int sz){FPS ans = low(sz);for (int i = 0; i + p < sz; i++) {ans[i + p] -= ans[i] * a;}return ans;}FPS inv(int sz) const{const int n = size();assert((*this)[0].val() != 0);const int N = n * 2 - 1;if (N <= (1 << mint::max2p())) {FPS r{(*this)[0].inv()};for (int lg = 0, m = 1; m < sz; m <<= 1, lg++) {FPS f{this->begin(), this->begin() + std::min(n, 2 * m)};FPS g = r;f.resize(2 * m), g.resize(2 * m);trans(f, lg + 1, false), trans(g, lg + 1, false);for (int i : rep(2 * m)) {f[i] *= g[i];}trans(f, lg + 1, true);std::fill(f.begin(), f.begin() + m, 0);trans(f, lg + 1, false);for (int i : rep(2 * m)) {f[i] *= g[i];}trans(f, lg + 1, true);for (int i = m; i < std::min(2 * m, sz); i++) {r[i] = -f[i];}}return r;} else {FPS g{(*this)[0].inv()};for (int lg = 0, m = 1; m < sz; m <<= 1, lg++) {g = FPS{2} * g - this->mult(g.mult(g, 2 * m), 2 * m);}return g.low(sz);}}FPS log(const int sz) const{assert((*this)[0].val() == 1);auto ans = derivative().mult(inv(sz), sz).integral();ans.resize(sz);return ans;}FPS exp(const int sz) const{const int l = lsb(sz);if (l == -1) { return FPS{1}.low(sz); }assert((*this)[0].val() == 0);const int n = size();const int N = n * 2 - 1;if (N <= (1 << mint::max2p())) {FPS f = {1, (*this)[1]}, g{1}, G{1, 1};for (int m = 2, lg = 1; m < sz; m <<= 1, lg++) {auto F = f;F.resize(2 * m), trans(F, lg + 1, false);FPS z(m);for (int i : rep(m)) {z[i] = F[i] * G[i];}trans(z, lg, true);std::fill(z.begin(), z.begin() + m / 2, 0);trans(z, lg, false);for (int i : rep(m)) {z[i] *= G[i];}trans(z, lg, true);for (int i : irange(m / 2, m)) {g[i] = -z[i];}G = g, G.resize(m * 2), trans(G, lg + 1, false);auto q = low(m).derivative();q.resize(m), trans(q, lg, false);for (int i : rep(m)) {q[i] *= F[i];}trans(q, lg, true);const auto df = f.derivative();for (int i : rep(m - 1)) {q[i] -= df[i];}q.resize(m * 2);for (int i : rep(m - 1)) {q[m + i] = q[i], q[i] = 0;}trans(q, lg + 1, false);for (int i : rep(m * 2)) {q[i] *= G[i];}trans(q, lg + 1, true);q.pop_back();q = q.integral();for (int i = m; i < std::min(size(), m * 2); i++) {q[i] += (*this)[i];}std::fill(q.begin(), q.begin() + m, 0);trans(q, lg + 1, false);for (int i = 0; i < m * 2; i++) {q[i] *= F[i];}trans(q, lg + 1, true);for (int i = m; i < 2 * m; i++) {f[i] = q[i];}}return f.low(sz);} else {FPS f{1};for (int m = 1; m < sz; m <<= 1) {auto g = low(2 * m);g[0] += 1;f.resize(2 * m);g -= f.log(2 * m);g = f.mult(g, 2 * m);for (int i = m; i < std::min(2 * m, g.size()); i++) {f[i] = g[i];}}return f.low(sz);}}template<typename I>FPS pow(I n) const{return pow(n, deg() * n + 1);}template<typename I>FPS pow(I n, int sz) const{if (n == 0) { return FPS{1}.low(sz); }if (size() == 0) { return FPS{}; }const int p = lsb(deg() / n);if (p == -1) { return FPS{}; }const mint a = (*this)[p];FPS f = (*this) >> p;for (auto& c : f) {c /= a;}f = f.log(sz - p * n);for (auto& c : f) {c *= n;}f = f.exp(sz - p * n);FPS g;for (int i : rep(f.size())) {g[i + p * n] = f[i] * a.pow(n);}return g;}FPS tshift(const mint& c) const{const int N = size();FPS f(N), d(N);for (int i = 0; i < N; i++) {d[i] = c.pow(N - 1 - i) * mint::ifact(N - 1 - i);}for (int i = 0; i < N; i++) {f[i] = (*this)[i] * mint::fact(i);}f = f * d;FPS g(N);for (int i = 0; i < N; i++) {g[i] = f[i + N - 1] * mint::ifact(i);}return g;}FPS quot(const FPS& g) const{const int N = size(), M = g.size();if (N < M) { return FPS{}; }const auto fR = rev(), gR = g.rev();return fR.mult(gR.inv(N - M + 1), N - M + 1).rev();}FPS rem(const FPS& g) const{return (*this) - g * quot(g);}private:int lsb() const{return lsb(deg());}int lsb(int sz) const{for (int p : rep(sz + 1)) {if ((*this)[p].val() != 0) { return p; }}return -1;}using submint1 = modint<469762049, 3, 26>;using submint2 = modint<167772161, 3, 25>;using submint3 = modint<754974721, 11, 24>;template<typename submint>static void trans(Vec<submint>& as, int lg, bool rev){const int N = 1 << lg;assert((int)as.size() == N);Vec<submint> rs, irs;if (rs.empty()) {const submint r = submint(submint::root()), ir = r.inv();rs.resize(submint::max2p() + 1), irs.resize(submint::max2p() + 1);rs.back() = -r.pow((submint::mod() - 1) >> submint::max2p()),irs.back() = -ir.pow((submint::mod() - 1) >> submint::max2p());for (u32 i : irange(submint::max2p(), 0, -1)) {rs[i - 1] = -(rs[i] * rs[i]);irs[i - 1] = -(irs[i] * irs[i]);}}const auto drange = (rev ? irange(0, lg, 1) : irange(lg - 1, -1, -1));for (const int d : drange) {const int width = 1 << d;submint e = 1;for (int i = 0, j = 1; i < N; i += width * 2, j++) {for (int l = i, r = i + width; l < i + width; l++, r++) {if (rev) {const submint x = as[l], y = as[r];as[l] = x + y, as[r] = (x - y) * e;} else {const submint x = as[l], y = as[r] * e;as[l] = x + y, as[r] = x - y;}}e *= (rev ? irs : rs)[lsbp1(j) + 1];}}if (rev) {const submint iN = submint{N}.inv();for (auto& a : as) {a *= iN;}}}template<typename submint>static Vec<submint> conv(const Vec<mint>& as, const Vec<mint>& bs, int sz){const int an = std::min((int)as.size(), sz);const int bn = std::min((int)bs.size(), sz);const int M = an + bn - 1;const int lg = clog(M);const int L = 1 << lg;Vec<submint> As(L), Bs(L);for (int i : rep(an)) {As[i] = as[i].val();}for (int i : rep(bn)) {Bs[i] = bs[i].val();}trans(As, lg, false), trans(Bs, lg, false);for (int i : rep(L)) {As[i] *= Bs[i];}trans(As, lg, true);const int N = std::min(sz, (int)as.size() + (int)bs.size() - 1);As.resize(N);return As;}static constexpr submint2 ip1 = submint2{submint1::mod()}.inv();static constexpr submint3 ip2 = submint3{submint2::mod()}.inv();static constexpr submint3 ip1p2 = submint3{submint1::mod()}.inv() * ip2;static constexpr mint p1(){return mint{submint1::mod()};}static constexpr mint p1p2(){return p1() * mint{submint2::mod()};}static constexpr mint restore(int x1, int x2, int x3){const int k0 = x1;const int k1 = (ip1 * (x2 - k0)).val();const int k2 = (ip1p2 * (x3 - k0) - ip2 * k1).val();return p1p2() * k2 + p1() * k1 + k0;}};template<typename mint, typename I>mint divNth(FPS<mint> f, FPS<mint> g, I N){if (f.size() == 0) { return 0; }const int n = g.size();int mi = 0;mint a;for (int i : rep(n)) {if (g[i].val() != 0) {mi = i;a = g[i];break;}}g >>= mi;const mint ia = a.inv();for (auto& c : f) {c *= ia;}for (auto& c : g) {c *= ia;}FPS p = f.quot(g);f -= g * p;N += mi;if (N < 0) { return 0; }const mint offset = p.at(N);for (; N > 0; N >>= 1) {FPS mg = g;for (int i = 1; i < n; i += 2) {mg[i] = -mg[i];}const auto fmg = f * mg;const auto gmg = g * mg;f.clear(), g.clear();for (int i = 0; i < gmg.size(); i += 2) {g[i >> 1] = gmg[i];}if (N % 2 == 0) {for (int i = 0; i < fmg.size(); i += 2) {f[i >> 1] = fmg[i];}} else {for (int i = 1; i < fmg.size(); i += 2) {f[i >> 1] = fmg[i];}}}return offset + f.at(0);}template<typename mint, typename I>mint nthTerm(const Vec<mint>& as, I N){const FPS g{berlekampMassey(as)};const int L = g.size();const auto f = FPS<mint>{as}.mult(g, L - 1);return divNth(f, g, N);}#pragma endregionint main(){using mint = modint_1000000007;const auto N = in.val<i64>() - 1;const auto [A, B, K] = in.tup<mint, mint, mint>();Vec<mint> As{A, B};for (int i : rep(100)) {const auto a = As[As.size() - 2], b = As[As.size() - 1];const auto c = (b * b + K) / a;As.push_back(c);}const auto ans = nthTerm(As, N);out.ln(ans);return 0;}