結果
問題 | No.658 テトラナッチ数列 Hard |
ユーザー | vabuff |
提出日時 | 2018-03-03 19:44:04 |
言語 | C++14 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 356 ms / 2,000 ms |
コード長 | 22,956 bytes |
コンパイル時間 | 1,533 ms |
コンパイル使用メモリ | 146,356 KB |
実行使用メモリ | 6,944 KB |
最終ジャッジ日時 | 2024-07-04 02:36:55 |
合計ジャッジ時間 | 4,079 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge3 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
6,816 KB |
testcase_01 | AC | 2 ms
6,944 KB |
testcase_02 | AC | 1 ms
6,940 KB |
testcase_03 | AC | 2 ms
6,940 KB |
testcase_04 | AC | 130 ms
6,940 KB |
testcase_05 | AC | 159 ms
6,940 KB |
testcase_06 | AC | 192 ms
6,940 KB |
testcase_07 | AC | 211 ms
6,940 KB |
testcase_08 | AC | 243 ms
6,940 KB |
testcase_09 | AC | 351 ms
6,940 KB |
testcase_10 | AC | 356 ms
6,944 KB |
ソースコード
/** * */ // #include {{{ #include <algorithm> #include <array> #include <bitset> #include <cassert> #include <cfloat> #include <chrono> #include <cmath> #include <cstdint> #include <cstdlib> #include <cstring> #include <ctime> #include <deque> #include <forward_list> #include <functional> #include <iomanip> #include <iostream> #include <fstream> #include <sstream> #include <iterator> #include <limits> #include <list> #include <map> #include <numeric> #include <queue> #include <random> #include <regex> #include <set> #include <stack> #include <string> #include <tuple> #include <type_traits> #include <unordered_map> #include <unordered_set> #include <utility> #include <vector> #ifdef LOCAL #include <fmt/format.h> #include <fmt/ostream.h> #endif using namespace std; // }}} // type {{{ using i8 = int8_t; using u8 = uint8_t; using i16 = int16_t; using u16 = uint16_t; using i32 = int32_t; using u32 = uint32_t; using i64 = int64_t; using u64 = uint64_t; using i128 = __int128_t; using u128 = __uint128_t; template<typename T> using MaxHeap = priority_queue<T, vector<T>, less<T>>; template<typename T> using MinHeap = priority_queue<T, vector<T>, greater<T>>; // }}} // hide {{{ #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-const-variable" #endif // }}} // 適宜調整 constexpr bool AUTOFLUSH = false; constexpr int IOS_PREC = 12; constexpr int INF_I32 = 1'010'000'000; constexpr i64 INF_I64 = 1'010'000'000'000'000'000LL; constexpr auto INF = INF_I64; constexpr double EPS = 1e-12; constexpr i64 MOD = 1'000'000'007; // hide {{{ #ifdef __clang__ #pragma clang diagnostic pop #endif // }}} // util {{{ constexpr i32 I32_MAX = numeric_limits<i32>::max(); constexpr i32 I32_MIN = numeric_limits<i32>::min(); constexpr i64 I64_MAX = numeric_limits<i64>::max(); constexpr i64 I64_MIN = numeric_limits<i64>::min(); constexpr double PI = 3.14159265358979323846; template<typename F> class RecursiveFunc { public: RecursiveFunc(F&& f) : f_(f) {} template<typename... Args> decltype(auto) operator()(Args&&... args) const { return f_(*this, forward<Args>(args)...); } private: F f_; }; template<typename F> auto RECURSIVE(F&& f) { return RecursiveFunc<decay_t<F>>(forward<F>(f)); } template<typename T> int GETBIT(T x, int i) { return (x>>i) & 1; } template<typename T> T SETBIT(T x, int i) { return x | (T(1)<<i); } template<typename T> T CLEARBIT(T x, int i) { return x & ~(T(1)<<i); } template<typename T> constexpr const T& MAX(const T& x, const T& y) { return std::max(x, y); } template<typename T, typename Comp> constexpr const T& MAX(const T& x, const T& y, Comp comp) { return std::max(x, y, comp); } template<typename T> constexpr T MAX(initializer_list<T> ilist) { return std::max(ilist); } template<typename T, typename Comp> constexpr T MAX(initializer_list<T> ilist, Comp comp) { return std::max(ilist, comp); } template<typename T> constexpr const T& MIN(const T& x, const T& y) { return std::min(x, y); } template<typename T, typename Comp> constexpr const T& MIN(const T& x, const T& y, Comp comp) { return std::min(x, y, comp); } template<typename T> constexpr T MIN(initializer_list<T> ilist) { return std::min(ilist); } template<typename T, typename Comp> constexpr T MIN(initializer_list<T> ilist, Comp comp) { return std::min(ilist, comp); } template<typename T> constexpr T ABS(T x) { static_assert(is_signed<T>::value, "ABS(): argument must be signed"); return x < 0 ? -x : x; } template<typename T> constexpr T abs_diff(T x, T y) { return x < y ? y-x : x-y; } template<typename T> constexpr bool is_odd(T x) { return x % 2 != 0; } template<typename T> constexpr bool is_even(T x) { return x % 2 == 0; } template<typename T> constexpr bool parity_same(T x, T y) { return (is_odd(x) && is_odd(y)) || (is_even(x) && is_even(y)); } template<typename T> constexpr int cmp(T x, T y) { return (y < x) - (x < y); } template<typename T> constexpr int sgn(T x) { return cmp(x, T(0)); } constexpr i64 ipow(i64 a, i64 b) { assert(b >= 0); i64 res(1); for(i64 i = 0; i < b; ++i) res *= a; return res; } pair<i64,i64> divmod(i64 a, i64 b) { return make_pair(a/b, a%b); } constexpr i64 div_ceil(i64 a, i64 b) { return a/b + (((a<0)^(b>0)) && (a%b)); } constexpr i64 div_floor(i64 a, i64 b) { return a/b - (((a>0)^(b>0)) && (a%b)); } constexpr i64 modulo(i64 a, i64 b) { assert(0 < b); i64 r = a % b; return r >= 0 ? r : r+b; } template<typename T> constexpr T CLAMP(T x, T lo, T hi) { assert(lo <= hi); if(x < lo) return lo; else if(hi < x) return hi; else return x; } template<typename T, typename U> bool chmax(T& xmax, const U& x) { if(xmax < x) { xmax = x; return true; } else { return false; } } template<typename T, typename U> bool chmin(T& xmin, const U& x) { if(x < xmin) { xmin = x; return true; } else { return false; } } template<typename T> constexpr int SIZE(const T& c) { return static_cast<int>(c.size()); } template<typename T, size_t N> constexpr int SIZE(const T (&)[N]) { return static_cast<int>(N); } template<typename InputIt, typename T> int argfind(InputIt first, InputIt last, const T& x) { auto it = find(first, last, x); return distance(first, it); } template<typename InputIt> int argmax(InputIt first, InputIt last) { auto it = max_element(first, last); return distance(first, it); } template<typename InputIt> int argmin(InputIt first, InputIt last) { auto it = min_element(first, last); return distance(first, it); } template<typename InputIt> bool alltrue(InputIt first, InputIt last) { return all_of(first, last, [](bool b) { return b; }); } template<typename InputIt> bool anytrue(InputIt first, InputIt last) { return any_of(first, last, [](bool b) { return b; }); } template<typename InputIt> bool allfalse(InputIt first, InputIt last) { return !anytrue(first, last); } template<typename InputIt> bool anyfalse(InputIt first, InputIt last) { return !alltrue(first, last); } // hash {{{ template<typename T> struct myhash { size_t operator()(const T& x) const { hash<T> h; return h(x); } }; template<typename T> size_t myhash_value(const T& x) { return hash<T>()(x); } template<typename T> void myhash_combine(size_t& seed, const T& x) { seed ^= myhash_value(x) + 0x9e3779b9 + (seed<<6) + (seed>>2); } template<typename T1, typename T2> struct myhash<pair<T1,T2>> { size_t operator()(const pair<T1,T2>& p) const { size_t seed = 0; myhash_combine(seed, p.first); myhash_combine(seed, p.second); return seed; } }; template<size_t I=0, typename... TS, enable_if_t<I == sizeof...(TS), nullptr_t> = nullptr> void TUPLEHASH(size_t&, const tuple<TS...>&) {} template<size_t I=0, typename... TS, enable_if_t<I < sizeof...(TS), nullptr_t> = nullptr> void TUPLEHASH(size_t& seed, const tuple<TS...>& t) { myhash_combine(seed, get<I>(t)); TUPLEHASH<I+1, TS...>(seed, t); } template<typename... TS> struct myhash<tuple<TS...>> { size_t operator()(const tuple<TS...>& t) const { size_t seed = 0; TUPLEHASH(seed, t); return seed; } }; template<typename Seq> void SEQHASH(size_t& seed, const Seq& v) { for(const auto& e : v) myhash_combine(seed, e); } template<typename T> struct myhash<vector<T>> { size_t operator()(const vector<T>& v) const { size_t seed = 0; SEQHASH(seed, v); return seed; } }; template<typename T, size_t N> struct myhash<array<T,N>> { size_t operator()(const array<T,N>& v) const { size_t seed = 0; SEQHASH(seed, v); return seed; } }; template<typename T> using HashSet = unordered_set<T,myhash<T>>; template<typename K, typename V> using HashMap = unordered_map<K,V,myhash<K>>; template<typename T> using HashMultiSet = unordered_multiset<T,myhash<T>>; template<typename K, typename V> using HashMultiMap = unordered_multimap<K,V,myhash<K>>; // }}} template<typename T, typename... Args> void vec_emplace_front(vector<T>& v, Args&&... args) { v.emplace(begin(v), args...); } template<typename K, typename V> pair<typename map<K,V>::iterator, bool> insert_or_assign(map<K,V>& m, const K& k, const V& v) { auto it = m.lower_bound(k); if(it != end(m) && !m.key_comp()(k,it->first)) { it->second = v; return make_pair(it, false); } else { auto it_ins = m.insert(it, make_pair(k,v)); return make_pair(it_ins, true); } } template<typename K, typename V> pair<typename HashMap<K,V>::iterator, bool> insert_or_assign(HashMap<K,V>& m, const K& k, const V& v) { auto it = m.find(k); if(it != end(m)) { it->second = v; return make_pair(it, false); } else { auto it_ins = m.insert(it, make_pair(k,v)); return make_pair(it_ins, true); } } template<typename T> string TO_STRING(const T& x) { ostringstream out; out << x; return out.str(); } template<typename InputIt> string JOIN(InputIt first, InputIt last, const string& sep) { ostringstream out; while(first != last) { out << *first++; if(first != last) out << sep; } return out.str(); } template<typename InputIt> auto SUM(InputIt first, InputIt last) { using T = typename iterator_traits<InputIt>::value_type; return accumulate(first, last, T()); } template<typename T> void UNIQ(T& c) { c.erase(unique(begin(c), end(c)), end(c)); } template<typename T, typename F> enable_if_t<rank<T>::value==0> ARRAY_FOREACH(T& e, F f) { f(e); } template<typename Array, typename F> enable_if_t<rank<Array>::value!=0> ARRAY_FOREACH(Array& ary, F f) { for(auto& e : ary) ARRAY_FOREACH(e, f); } template<typename Array, typename U> enable_if_t<rank<Array>::value!=0> ARRAY_FILL(Array& ary, const U& v) { ARRAY_FOREACH(ary, [&v](auto& elem) { elem = v; }); } template<typename T> T POP_BACK(vector<T>& que) { T x = que.back(); que.pop_back(); return x; } template<typename T> T POP_BACK(deque<T>& que) { T x = que.back(); que.pop_back(); return x; } template<typename T> T POP_FRONT(deque<T>& que) { T x = que.front(); que.pop_front(); return x; } template<typename T, typename C> T POP(stack<T,C>& stk) { T x = stk.top(); stk.pop(); return x; } template<typename T, typename C> T POP(queue<T,C>& que) { T x = que.front(); que.pop(); return x; } template<typename T, typename Cont, typename Cmp> T POP(priority_queue<T,Cont,Cmp>& que) { T x = que.top(); que.pop(); return x; } template<typename T> void RD(T& x) { cin >> x; #ifdef LOCAL if(!cin) assert(false); #endif } template<typename T> void RD(vector<T>& v, int n) { v.reserve(n); for(int i = 0; i < n; ++i) { T e; RD(e); v.emplace_back(e); } } template<typename T, size_t N> void RD(array<T,N>& v) { for(size_t i = 0; i < N; ++i) { RD(v[i]); } } // 出力 {{{ // FPRINTSEQ {{{ template<typename InputIt> ostream& FPRINTSEQ(ostream& out, InputIt first, InputIt last) { while(first != last) { out << *first++; if(first != last) out << ' '; } return out; } template<typename InputIt> ostream& PRINTSEQ(InputIt first, InputIt last) { return FPRINTSEQ(cout, first, last); } template<typename InputIt> ostream& DPRINTSEQ(InputIt first, InputIt last) { #ifdef LOCAL FPRINTSEQ(cerr, first, last); #endif return cerr; } // }}} // 1次元生配列 {{{ template<typename T, size_t N> ostream& FPRINTARRAY1(ostream& out, const T (&c)[N]) { return FPRINTSEQ(out, begin(c), end(c)); } template<typename T, size_t N> ostream& PRINTARRAY1(const T (&c)[N]) { return FPRINTARRAY1(cout, c); } template<typename T, size_t N> ostream& DPRINTARRAY1(const T (&c)[N]) { #ifdef LOCAL FPRINTARRAY1(cerr, c); #endif return cerr; } // }}} // 2次元生配列 {{{ template<typename T, size_t N1, size_t N2> ostream& FPRINTARRAY2(ostream& out, const T (&c)[N1][N2]) { out << '\n'; for(const auto& e : c) { FPRINTARRAY1(out, e) << '\n'; } return out; } template<typename T, size_t N1, size_t N2> ostream& PRINTARRAY2(const T (&c)[N1][N2]) { return FPRINTARRAY2(cout, c); } template<typename T, size_t N1, size_t N2> ostream& DPRINTARRAY2(const T (&c)[N1][N2]) { #ifdef LOCAL FPRINTARRAY2(cerr, c); #endif return cerr; } // }}} // 非mapコンテナ {{{ template<typename T> ostream& operator<<(ostream& out, const vector<T>& c) { return FPRINTSEQ(out, begin(c), end(c)); } // 特別扱い template<typename T> ostream& operator<<(ostream& out, const vector<vector<T>>& c) { out << '\n'; for(const auto& e : c) { out << e << '\n'; } return out; } // 特別扱い ostream& operator<<(ostream& out, const vector<string>& c) { out << '\n'; for(const string& e : c) { out << e << '\n'; } return out; } template<typename T> ostream& operator<<(ostream& out, const deque<T>& c) { return FPRINTSEQ(out, begin(c), end(c)); } template<typename T> ostream& operator<<(ostream& out, const set<T>& c) { return FPRINTSEQ(out, begin(c), end(c)); } template<typename T> ostream& operator<<(ostream& out, const HashSet<T>& c) { return out << set<T>(begin(c), end(c)); } template<typename T> ostream& operator<<(ostream& out, const multiset<T>& c) { return FPRINTSEQ(out, begin(c), end(c)); } template<typename T> ostream& operator<<(ostream& out, const HashMultiSet<T>& c) { return out << multiset<T>(begin(c), end(c)); } template<typename T, size_t N> ostream& operator<<(ostream& out, const array<T,N>& c) { return FPRINTSEQ(out, begin(c), end(c)); } // }}} // mapコンテナ {{{ template<typename InputIt> ostream& FPRINTMAP(ostream& out, InputIt first, InputIt last) { out << "{\n"; for(auto it = first; it != last; ++it) { out << " " << it->first << " : " << it->second << '\n'; } out << "}\n"; return out; } template<typename InputIt> ostream& PRINTMAP(InputIt first, InputIt last) { return FPRINTMAP(cout, first, last); } template<typename InputIt> ostream& DPRINTMAP(InputIt first, InputIt last) { #ifdef LOCAL FPRINTMAP(cerr, first, last); #endif return cerr; } template<typename K, typename V> ostream& operator<<(ostream& out, const map<K,V>& c) { return FPRINTMAP(out, begin(c), end(c)); } template<typename K, typename V> ostream& operator<<(ostream& out, const HashMap<K,V>& c) { return out << map<K,V>(begin(c), end(c)); } template<typename K, typename V> ostream& operator<<(ostream& out, const multimap<K,V>& c) { return FPRINTMAP(out, begin(c), end(c)); } template<typename K, typename V> ostream& operator<<(ostream& out, const HashMultiMap<K,V>& c) { return out << multimap<K,V>(begin(c), end(c)); } // }}} // stack/queue/priority_queue {{{ template<typename T, typename C> ostream& operator<<(ostream& out, stack<T,C> c) { while(!c.empty()) { out << c.top(); c.pop(); if(!c.empty()) out << ' '; } return out; } template<typename T, typename C> ostream& operator<<(ostream& out, queue<T,C> c) { while(!c.empty()) { out << c.front(); c.pop(); if(!c.empty()) out << ' '; } return out; } template<typename T, typename Cont, typename Cmp> ostream& operator<<(ostream& out, priority_queue<T,Cont,Cmp> c) { while(!c.empty()) { out << c.top(); c.pop(); if(!c.empty()) out << ' '; } return out; } // }}} // pair/tuple {{{ template<typename T1, typename T2> ostream& operator<<(ostream& out, const pair<T1,T2>& p) { return out << '(' << p.first << ',' << p.second << ')'; } template<size_t I=0, typename... TS, enable_if_t<I == sizeof...(TS), nullptr_t> = nullptr> ostream& FPRINTTUPLE(ostream& out, const tuple<TS...>&) { if(sizeof...(TS) == 0) out << '('; return out << ')'; } template<size_t I=0, typename... TS, enable_if_t<I < sizeof...(TS), nullptr_t> = nullptr> ostream& FPRINTTUPLE(ostream& out, const tuple<TS...>& t) { if(I == 0) out << '('; else out << ','; out << get<I>(t); return FPRINTTUPLE<I+1, TS...>(out, t); } template<typename... TS> ostream& operator<<(ostream& out, const tuple<TS...>& t) { return FPRINTTUPLE(out, t); } // }}} // PRINT {{{ ostream& FPRINT(ostream& out) { return out; } template<typename T, typename... TS> ostream& FPRINT(ostream& out, const T& x, const TS& ...args) { out << x; if(sizeof...(args)) out << ' '; return FPRINT(out, args...); } template<typename... TS> ostream& FPRINTLN(ostream& out, const TS& ...args) { FPRINT(out, args...); return out << '\n'; } template<typename... TS> ostream& PRINT(const TS& ...args) { return FPRINT(cout, args...); } template<typename... TS> ostream& PRINTLN(const TS& ...args) { return FPRINTLN(cout, args...); } template<typename... TS> ostream& DPRINT(const TS& ...args) { #ifdef LOCAL FPRINT(cerr, args...); #endif return cerr; } template<typename... TS> ostream& DPRINTLN(const TS& ...args) { #ifdef LOCAL FPRINTLN(cerr, args...); #endif return cerr; } // }}} // }}} void FLUSH() { cout.flush(); } [[noreturn]] void EXIT() { #ifdef LOCAL cout.flush(); cerr.flush(); #else FLUSH(); #endif //quick_exit(0); // does not work on codeforces _Exit(0); } struct IoInit { IoInit() { #ifndef LOCAL cin.tie(nullptr); ios::sync_with_stdio(false); #endif cout << fixed << setprecision(IOS_PREC); #ifdef LOCAL cerr << fixed << setprecision(IOS_PREC); #endif if(AUTOFLUSH) cout << unitbuf; } } IOINIT; #define FOR(i, start, end) for(i64 i = (start); i < (end); ++i) #define REP(i, n) FOR(i, 0, n) #define ALL(f,c,...) (([&](decltype((c)) cc) { return (f)(begin(cc), end(cc), ## __VA_ARGS__); })(c)) #define GENERIC(f) ([](auto&&... args) -> decltype(auto) { return (f)(forward<decltype(args)>(args)...); }) #define DBG(x) DPRINTLN('L', __LINE__, ':', #x, ':', (x)) #define PAIR make_pair #define TUPLE make_tuple // }}} /** * a^b (mod m) * * 事前条件: * a >= 0 && b >= 0 */ i64 pow_modulo(i64 a, i64 b, i64 m) { i64 res = 1; for(; b > 0; b >>= 1) { if(b & 1) { res *= a; res %= m; } a *= a; a %= m; } return res; } /** * mod p での a の逆元 */ i64 inv_modulo(i64 a, i64 p) { return pow_modulo(a, p-2, p); } /** * mod p 上での演算をクラス化してみるテスト * p は素数とする */ template<i64 P> class ModPT { public: ModPT() : v_(0) {} ModPT(i64 v) : v_(v%P) {} ModPT& operator+=(const ModPT& rhs) { v_ += rhs.v_; v_ %= P; return *this; } ModPT& operator-=(const ModPT& rhs) { v_ = (v_+P) - rhs.v_; v_ %= P; return *this; } ModPT& operator*=(const ModPT& rhs) { v_ *= rhs.v_; v_ %= P; return *this; } ModPT inv() const { return ModPT(inv_modulo(v_, P)); } ModPT pow(i64 x) const { return ModPT(pow_modulo(v_, x, P)); } friend ostream& operator<<(ostream& out, const ModPT<P>& a) { return out << a.v_; } private: i64 v_; }; template<i64 P> const ModPT<P> operator+(const ModPT<P>& lhs, const ModPT<P>& rhs) { return ModPT<P>(lhs) += rhs; } template<i64 P> const ModPT<P> operator+(const ModPT<P>& lhs, i64 rhs) { return ModPT<P>(lhs) += rhs; } template<i64 P> const ModPT<P> operator+(i64 lhs, const ModPT<P>& rhs) { return ModPT<P>(rhs) += lhs; } template<i64 P> const ModPT<P> operator-(const ModPT<P>& lhs, const ModPT<P>& rhs) { return ModPT<P>(lhs) -= rhs; } template<i64 P> const ModPT<P> operator-(const ModPT<P>& lhs, i64 rhs) { return ModPT<P>(lhs) -= rhs; } template<i64 P> const ModPT<P> operator-(i64 lhs, const ModPT<P>& rhs) { return ModPT<P>(rhs) -= lhs; } template<i64 P> const ModPT<P> operator*(const ModPT<P>& lhs, const ModPT<P>& rhs) { return ModPT<P>(lhs) *= rhs; } template<i64 P> const ModPT<P> operator*(const ModPT<P>& lhs, i64 rhs) { return ModPT<P>(lhs) *= rhs; } template<i64 P> const ModPT<P> operator*(i64 lhs, const ModPT<P>& rhs) { return ModPT<P>(rhs) *= lhs; } template<typename T> T fastpow(T a, i64 b, const T& id) { T res = id; for(; b > 0; b >>= 1) { if(b & 1) res *= a; a *= a; } return res; } template<typename T> class Matrix { public: static Matrix zero(int nr, int nc) { return Matrix(nr, nc); } static Matrix id(int nr, int nc) { assert(nr == nc); Matrix ret(nr, nc); REP(i, nr) { ret.at(i,i) = T(1); } return ret; } Matrix(int nr, int nc) : mat_(nr,vector<T>(nc)) {} Matrix(const vector<vector<T>>& mat) : mat_(mat) {} int nrow() const { return SIZE(mat_); } int ncol() const { return SIZE(mat_[0]); } T& at(int r, int c) { return mat_[r][c]; } const T& at(int r, int c) const { return mat_[r][c]; } Matrix& operator+=(const Matrix& rhs) { REP(r, nrow()) REP(c, ncol()) { at(r,c) += rhs.at(r,c); } return *this; } Matrix& operator-=(const Matrix& rhs) { REP(r, nrow()) REP(c, ncol()) { at(r,c) -= rhs.at(r,c); } return *this; } Matrix& operator*=(const Matrix& rhs) { return *this = *this * rhs; } friend ostream& operator<<(ostream& out, const Matrix& m) { return out << m.mat_; } private: vector<vector<T>> mat_; }; template<typename T> const Matrix<T> operator*(const Matrix<T>& lhs, const Matrix<T>& rhs) { assert(lhs.ncol() == rhs.nrow()); int nr = lhs.nrow(); int nc = rhs.ncol(); int m = lhs.ncol(); Matrix<T> res(nr, nc); REP(r, nr) REP(c, nc) { REP(i, m) { res.at(r,c) += lhs.at(r,i) * rhs.at(i,c); } } return res; } using ModP = ModPT<17>; ModP f(i64 n) { assert(n >= 1); if(n <= 3) return 0; if(n == 4) return 1; Matrix<ModP> m(vector<vector<ModP>> { { 1, 1, 1, 1 }, { 1, 0, 0, 0 }, { 0, 1, 0, 0 }, { 0, 0, 1, 0 }, }); Matrix<ModP> a(vector<vector<ModP>> { { 1 }, { 0 }, { 0 }, { 0 }, }); Matrix<ModP> mp = fastpow(m, n-4, Matrix<ModP>::id(4,4)); //DBG(mp); Matrix<ModP> res = mp * a; return res.at(0,0); } void solve() { i64 Q; RD(Q); REP(_, Q) { i64 n; RD(n); PRINTLN(f(n)); } } signed main(signed /*argc*/, char** /*argv*/) { solve(); EXIT(); }