結果
問題 | No.3038 フィボナッチ数列の周期 |
ユーザー | toriaezuAC |
提出日時 | 2018-04-02 23:56:53 |
言語 | C++14 (gcc 12.3.0 + boost 1.83.0) |
結果 |
WA
|
実行時間 | - |
コード長 | 12,158 bytes |
コンパイル時間 | 1,511 ms |
コンパイル使用メモリ | 136,856 KB |
実行使用メモリ | 5,376 KB |
最終ジャッジ日時 | 2024-06-26 06:53:40 |
合計ジャッジ時間 | 2,698 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge3 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | WA | - |
testcase_01 | WA | - |
testcase_02 | WA | - |
testcase_03 | WA | - |
testcase_04 | WA | - |
testcase_05 | WA | - |
testcase_06 | AC | 2 ms
5,376 KB |
testcase_07 | WA | - |
testcase_08 | WA | - |
testcase_09 | WA | - |
testcase_10 | WA | - |
testcase_11 | WA | - |
testcase_12 | WA | - |
testcase_13 | WA | - |
testcase_14 | WA | - |
testcase_15 | WA | - |
testcase_16 | WA | - |
testcase_17 | WA | - |
testcase_18 | WA | - |
testcase_19 | WA | - |
testcase_20 | WA | - |
testcase_21 | WA | - |
testcase_22 | WA | - |
testcase_23 | WA | - |
testcase_24 | WA | - |
ソースコード
#ifndef __INTMOD_H__0001__ #define __INTMOD_H__0001__ #include <vector> #include <iostream> #include <cassert> #include <iostream> /* Modulus must be less than 0x80000000, and not be 0. */ template <uint32_t Modulus> class IntMod { typedef int32_t Int; typedef uint32_t UInt; typedef long long Long; typedef uint64_t ULong; public: template <uint32_t Modulus_> friend bool operator==(const IntMod<Modulus_>& left, const IntMod<Modulus_>& right); template <uint32_t Modulus_> friend bool operator!=(const IntMod<Modulus_>& left, const IntMod<Modulus_>& right); template <uint32_t Modulus_> friend bool operator<(const IntMod<Modulus_>& left, const IntMod<Modulus_>& right); template <uint32_t Modulus_> friend bool operator<=(const IntMod<Modulus_>& left, const IntMod<Modulus_>& right); template <uint32_t Modulus_> friend bool operator>(const IntMod<Modulus_>& left, const IntMod<Modulus_>& right); template <uint32_t Modulus_> friend bool operator>=(const IntMod<Modulus_>& left, const IntMod<Modulus_>& right); private: UInt value_m; public: IntMod() { value_m = 0; } IntMod(UInt value) { value_m = value % Modulus; } IntMod(ULong value) { value_m = value % Modulus; } IntMod(Int value) { Int tmp = value % (Int)Modulus; value_m = tmp >= 0 ? tmp : Modulus - (unsigned int)(-tmp); } IntMod(Long value) { Int tmp = value % (Long)Modulus; value_m = tmp >= 0 ? tmp : Modulus - (unsigned int)(-tmp); } IntMod(const IntMod& other) : value_m(other.value_m) {} IntMod& operator=(const IntMod& other) { value_m = other.value_m; return *this; } const IntMod& operator+() const { return *this; } IntMod operator-() const { return IntMod(Modulus - value_m); } IntMod& operator++() { ++value_m; if (value_m == Modulus) value_m = 0; return *this; } IntMod& operator--() { if (value_m == 0) value_m = Modulus; --value_m; return *this; } IntMod operator++(int dummy) { IntMod tmp(*this); ++(*this); return tmp; } IntMod operator--(int dummy) { IntMod tmp(*this); --(*this); return tmp; } IntMod& operator+=(const IntMod& right) { value_m += right.value_m; // value_m < 0x80000000 if (value_m >= Modulus) value_m -= Modulus; return *this; } IntMod& operator-=(const IntMod& right) { if (value_m < right.value_m) value_m += Modulus; value_m -= right.value_m; return *this; } IntMod& operator*=(const IntMod& right) { value_m = ((ULong)value_m * right.value_m) % Modulus; return *this; } IntMod& operator/=(const IntMod& right) { (*this) *= (right.Inverse()); return *this; } // for power IntMod operator[](ULong exp) const { return Pow(exp); } /* Modulus must be a prime. */ IntMod Inverse() const { return (*this).Pow(Modulus - 2); } IntMod Pow(ULong exp) const { IntMod product = 1; IntMod factor(*this); while (exp > 0) { if (exp & 1) product *= factor; factor *= factor; exp >>= 1; } return product; } UInt Get_value() const { return value_m; } static IntMod Fact(UInt num) { static std::vector<IntMod> table(1, 1); if (table.size() > num) return table[num]; int old_size = table.size(); table.resize(num + 1); for (int i = old_size; i <= num; i++) { table[i] = table[i - 1] * i; } return table[num]; } static IntMod Combi(UInt n, UInt r) { if (n < r) throw "okashii"; return IntMod::Fact(n) / (IntMod::Fact(n - r) * IntMod::Fact(r)); } static std::vector<IntMod> Inverse_list(int size) { assert(size < Modulus); std::vector<IntMod> ret_arr(size + 1); ret_arr[1] = 1; for (int i = 2; i <= size; ++i) { ret_arr[i] = ((ULong)(Modulus - Modulus / i) * ret_arr[Modulus % i].Get_value()) % Modulus; } return ret_arr; } }; template <uint32_t Modulus> IntMod<Modulus> operator+(const IntMod<Modulus>& left, const IntMod<Modulus>& right) { IntMod<Modulus> ret(left); ret += right; return ret; } template <uint32_t Modulus> IntMod<Modulus> operator-(const IntMod<Modulus>& left, const IntMod<Modulus>& right) { IntMod<Modulus> ret(left); ret -= right; return ret; } template <uint32_t Modulus> IntMod<Modulus> operator*(const IntMod<Modulus>& left, const IntMod<Modulus>& right) { IntMod<Modulus> ret(left); ret *= right; return ret; } template <uint32_t Modulus> IntMod<Modulus> operator/(const IntMod<Modulus>& left, const IntMod<Modulus>& right) { IntMod<Modulus> ret(left); ret /= right; return ret; } template <uint32_t Modulus> bool operator==(const IntMod<Modulus>& left, const IntMod<Modulus>& right) { return left.value_m == right.value_m; } template <uint32_t Modulus> bool operator!=(const IntMod<Modulus>& left, const IntMod<Modulus>& right) { return left.value_m != right.value_m; } /* for set/map */ template <uint32_t Modulus> bool operator<(const IntMod<Modulus>& left, const IntMod<Modulus>& right) { return left.value_m < right.value_m; } template <uint32_t Modulus> bool operator<=(const IntMod<Modulus>& left, const IntMod<Modulus>& right) { return left.value_m <= right.value_m; } template <uint32_t Modulus> bool operator>(const IntMod<Modulus>& left, const IntMod<Modulus>& right) { return left.value_m > right.value_m; } template <uint32_t Modulus> bool operator>=(const IntMod<Modulus>& left, const IntMod<Modulus>& right) { return left.value_m >= right.value_m; } template <uint32_t Modulus, class Integer> IntMod<Modulus> operator+(const IntMod<Modulus>& left, Integer right) { return left + IntMod<Modulus>(right); } template <uint32_t Modulus, class Integer> IntMod<Modulus> operator+(Integer left, const IntMod<Modulus>& right) { return IntMod<Modulus>(left) + right; } template <uint32_t Modulus, class Integer> IntMod<Modulus> operator-(const IntMod<Modulus>& left, Integer right) { return left - IntMod<Modulus>(right); } template <uint32_t Modulus, class Integer> IntMod<Modulus> operator-(Integer left, const IntMod<Modulus>& right) { return IntMod<Modulus>(left) - right; } template <uint32_t Modulus, class Integer> IntMod<Modulus> operator*(const IntMod<Modulus>& left, Integer right) { return left * IntMod<Modulus>(right); } template <uint32_t Modulus, class Integer> IntMod<Modulus> operator*(Integer left, const IntMod<Modulus>& right) { return IntMod<Modulus>(left) * right; } template <uint32_t Modulus, class Integer> IntMod<Modulus> operator/(const IntMod<Modulus>& left, Integer right) { return left / IntMod<Modulus>(right); } template <uint32_t Modulus, class Integer> IntMod<Modulus> operator/(Integer left, const IntMod<Modulus>& right) { return IntMod<Modulus>(left) / right; } template <uint32_t Modulus> std::istream& operator<<(std::istream& ist, const IntMod<Modulus>& val) { uint64_t tmp; ist >> tmp; val = tmp; return ist; } template <uint32_t Modulus> std::ostream& operator<<(std::ostream& ost, const IntMod<Modulus>& val) { ost << val.Get_value(); return ost; } typedef IntMod<1000000007> MInt; #if 1 MInt operator"" _m(unsigned long long num) { return MInt((uint64_t)num); } #endif #endif #define _CRT_SECURE_NO_WARNINGS #define _SCL_SECURE_NO_WARNINGS #include <cstdio> #include <cstdlib> #include <cstring> #include <cassert> #include <iostream> #include <string> #include <vector> #include <list> #include <utility> #include <algorithm> #include <functional> #include <cmath> #include <stack> #include <queue> #include <set> #include <map> #include <iomanip> #include <sstream> #include <bitset> #include <limits> #include <numeric> #include <valarray> #include <fstream> using namespace std; typedef unsigned int uint; typedef long long LL; typedef unsigned long long ULL; typedef pair<LL, LL> PP; #define REP(i, a, n) for(LL i = (a), i##_max = (n); i < i##_max; ++i) #define REM(i, a, n) for(LL i = (LL)(n) - 1, i##min = (a); i >= i##min; --i) #define ALL(arr) (arr).begin(), (arr).end() #define FLOAT fixed << setprecision(16) #define SPEEDUP {cin.tie(NULL); ios::sync_with_stdio(false);} const int INF = 0x3FFFFFFF; const LL INFLL = 0x3FFFFFFF3FFFFFFF; const double INFD = 1.0e+308; const string INFSTR = "\x7f"; const double EPS = 1.0e-9; void YesNo(bool b) { cout << (b ? "Yes" : "No") << endl; } void YESNO(bool b) { cout << (b ? "YES" : "NO") << endl; } template <class T, class U> istream& operator>>(istream& ist, pair<T, U>& right) { return ist >> right.first >> right.second; } template <class T, class U> ostream& operator<<(ostream& ost, const pair<T, U>& right) { return ost << right.first << ' ' << right.second; } template <class T, class TCompatible, size_t N> void Fill(T(&dest)[N], const TCompatible& val) { fill(dest, dest + N, val); } template <class T, class TCompatible, size_t M, size_t N> void Fill(T(&dest)[M][N], const TCompatible& val) { for (int i = 0; i < M; ++i) Fill(dest[i], val); } template<class T> T Compare(T left, T right) { return left > right ? 1 : (left < right ? -1 : 0); } istream& Ignore(istream& ist) { string s; ist >> s; return ist; } bool Inside(int i, int j, int h, int w) { return i >= 0 && i < h && j >= 0 && j < w; } template <class T> T Next() { T buf; cin >> buf; return buf; } #ifdef ONLY_MY_ENVIR #include "IntMod.h" #include "Union_Find.h" #include "Graph.h" #include "Range.h" #include "Global.h" #include "Flow_Solver.h" #include "Tree.h" #include "Suffix_Array.h" #include "Geometry.h" #include "Matrix.h" #include "Segment_Tree.h" #include "Rational.h" #include "Position.h" #endif #ifdef __GNUC__ typedef __int128 LLL; istream& operator>> (istream& ist, __int128& val) { LL tmp; ist >> tmp; val = tmp; return ist; } ostream& operator<< (ostream& ost, __int128 val) { LL tmp = val; ost << tmp; return ost; } #endif #if 1234567891 #include <array> #include <random> #include <unordered_set> #include <unordered_map> template<typename T> using PriorityQ = priority_queue<T, vector<T>, greater<T> >; // コスト小を優先 template <class T> auto Is(const T& value) { return [value](const auto& comparand) -> bool { return comparand == value; }; } #endif struct Mat { ULL a, b, c, d; }; Mat operator*(const Mat& p, const Mat& q) { return { p.a * q.a + p.b * q.c, p.a * q.b + p.b * q.d, p.c * q.a + p.d * q.c, p.c * q.b + p.d * q.d }; } Mat operator%(const Mat& p, uint mod) { return { p.a % mod, p.b % mod, p.c % mod, p.d % mod }; } Mat Pow(const Mat& p, uint exp, uint mod) { if (exp == 0) return Mat{ 1, 0, 0, 1 }; if (exp % 2 == 1) return p * Pow(p, exp - 1, mod) % mod; Mat tmp = Pow(p, exp / 2, mod); return tmp * tmp % mod; } bool Is_unit(const Mat& p) { return p.a == 1 && p.b == 0 && p.c == 0 && p.d == 1; } map<uint, uint> Factor(uint n) { map<uint, uint> ret; for (int i = 2; i * i <= n; ++i) { while (n % i == 0) { n /= i; ++ret[i]; } } if (n != 1) ++ret[n]; return ret; } uint Pow(uint base, uint exp) { if (exp == 0) return 1; if (exp % 2 == 1) return base * Pow(base, exp - 1); uint tmp = Pow(base, exp / 2); return tmp * tmp; } uint Period(uint mod, uint expected_period) { const auto& factors = Factor(expected_period); const int N = factors.size(); const Mat fib_gene = Mat{ 1, 1, 1, 0 }; vector<Mat> mats; for (auto factor : factors) { mats.push_back(Pow(fib_gene, factor.first, mod)); } uint mn = 0xffffffff; vector<int> curr(N, 0); //curr.back() = 1; while (curr[0] <= factors.begin()->second) { Mat product = fib_gene; auto fit = factors.cbegin(); for (int i = 0; i < N; ++i, ++fit) { for (int j = 0; j < curr[i]; ++j) { product = Pow(product, fit->first, mod); } } if (Is_unit(product)) { uint ans = 1; auto it = factors.cbegin(); for (int i = 0; i < N; ++i, ++it) { ans *= Pow(it->first, curr[i]); } mn = min(mn, ans); } ++curr.back(); auto it = prev(factors.cend()); for (int i = N - 1; i > 0 && curr[i] > it->second; --i, --it) { curr[i] = 0; ++curr[i - 1]; } } return mn; } int main() { int N; cin >> N; MInt ans = 1; for (int i = 0; i < N; ++i) { uint p, k; cin >> p >> k; uint period; if (p == 2) { period = 3; } else if (p == 5) { period = 20; } else { uint r = p * p % 5; uint expected_period = (r == 1 ? p - 1 : 2 * p + 2); period = Period(p, expected_period); } ans *= period * MInt(p)[k - 1]; } cout << ans << endl; return 0; }