#include <algorithm> #include <iostream> #include <vector> using namespace std; const int MAX_DIGITS = 18; const long long MODULO = 1000000000000000000LL; // 10 ^ MAX_DIGITS const int DIGITS_FIB[MAX_DIGITS] = { 0, 7, 12, 17, 21, 26, 31, 36, 40, 45, 50, 55, 60, 64, 69, 74, 79, 84, }; long long addMod(long long a, long long b) { a %= MODULO; b %= MODULO; long long result = a - MODULO + b; return result < 0? result + MODULO : result; } long long multMod(long long a, long long b) { a %= MODULO; b %= MODULO; if(a < b) { swap(a, b); } long long result = 0; while(a != 0) { if(a & 1) { result = addMod(result, b); } a >>= 1; b = addMod(b, b); } return result; } int bitLength(long long n) { int result = 0; while(n > 0) { ++result; n /= 2; } return result; } long long fibonacci(long long n) { long long f0 = 0, f1 = 1; for(int i = bitLength(n) - 1; i >= 0; --i) { long long f2 = multMod(f0, addMod(MODULO - f0, 2 * f1)); long long f3 = addMod(multMod(f0, f0), multMod(f1, f1)); f0 = f2; f1 = f3; if((n >> i) & 1 == 1) { f2 = addMod(f0, f1); f0 = f1; f1 = f2; } } return f0; } int main() { string suffix; cin >> suffix; long long periods[MAX_DIGITS + 1]; periods[0] = 1; periods[1] = 60; periods[2] = 300; periods[3] = 1500; for(int i = 4; i <= MAX_DIGITS; ++i) { periods[i] = periods[i - 1] * 10; } vector<long long> candidates; candidates.push_back(0); long long last = 0, power = 1; for(int i = 0; i < suffix.length(); ++i) { last = power * (suffix[suffix.length() - i - 1] - '0') + last; power *= 10; vector<long long> newCandidates; for(vector<long long>::iterator it = candidates.begin(); it != candidates.end(); ++it) { for(long long j = *it; j < periods[i + 1]; j += periods[i]) { if(fibonacci(j) % power == last) { newCandidates.push_back(j); } } } newCandidates.swap(candidates); } for(vector<long long>::iterator it = candidates.begin(); it != candidates.end(); ++it) { if(*it >= DIGITS_FIB[suffix.length() - 1]) { cout << *it << endl; return 0; } } cout << "NIE" << endl; return 0; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | #include <algorithm> #include <iostream> #include <vector> using namespace std; const int MAX_DIGITS = 18; const long long MODULO = 1000000000000000000LL; // 10 ^ MAX_DIGITS const int DIGITS_FIB[MAX_DIGITS] = { 0, 7, 12, 17, 21, 26, 31, 36, 40, 45, 50, 55, 60, 64, 69, 74, 79, 84, }; long long addMod(long long a, long long b) { a %= MODULO; b %= MODULO; long long result = a - MODULO + b; return result < 0? result + MODULO : result; } long long multMod(long long a, long long b) { a %= MODULO; b %= MODULO; if(a < b) { swap(a, b); } long long result = 0; while(a != 0) { if(a & 1) { result = addMod(result, b); } a >>= 1; b = addMod(b, b); } return result; } int bitLength(long long n) { int result = 0; while(n > 0) { ++result; n /= 2; } return result; } long long fibonacci(long long n) { long long f0 = 0, f1 = 1; for(int i = bitLength(n) - 1; i >= 0; --i) { long long f2 = multMod(f0, addMod(MODULO - f0, 2 * f1)); long long f3 = addMod(multMod(f0, f0), multMod(f1, f1)); f0 = f2; f1 = f3; if((n >> i) & 1 == 1) { f2 = addMod(f0, f1); f0 = f1; f1 = f2; } } return f0; } int main() { string suffix; cin >> suffix; long long periods[MAX_DIGITS + 1]; periods[0] = 1; periods[1] = 60; periods[2] = 300; periods[3] = 1500; for(int i = 4; i <= MAX_DIGITS; ++i) { periods[i] = periods[i - 1] * 10; } vector<long long> candidates; candidates.push_back(0); long long last = 0, power = 1; for(int i = 0; i < suffix.length(); ++i) { last = power * (suffix[suffix.length() - i - 1] - '0') + last; power *= 10; vector<long long> newCandidates; for(vector<long long>::iterator it = candidates.begin(); it != candidates.end(); ++it) { for(long long j = *it; j < periods[i + 1]; j += periods[i]) { if(fibonacci(j) % power == last) { newCandidates.push_back(j); } } } newCandidates.swap(candidates); } for(vector<long long>::iterator it = candidates.begin(); it != candidates.end(); ++it) { if(*it >= DIGITS_FIB[suffix.length() - 1]) { cout << *it << endl; return 0; } } cout << "NIE" << endl; return 0; } |