#include <unordered_map> #include <cstring> #include <cstdio> #include <vector> using namespace std; typedef long long LL; namespace mul { LL mul(LL a, LL b, LL mod) { LL res = 0; while (a) { if (a % 2) { res = res + b; if (res >= mod) res -= mod; } a /= 2; b = b + b; if (b >= mod) b -= mod; } return res; } }; #define PB push_back LL MOD; struct Fmatrix { LL m[2][2]; Fmatrix() { m[0][0] = m[0][1] = m[1][0] = 1; m[1][1] = 0; } }; Fmatrix operator*(const Fmatrix &lhs, const Fmatrix &rhs) { Fmatrix res; res.m[0][0] = res.m[0][1] = res.m[1][0] = res.m[1][1] = 0; for (int i=0;i<2;i++) for (int j=0;j<2;j++) for (int k=0;k<2;k++) res.m[i][j] = (res.m[i][j] + mul::mul(lhs.m[i][k], rhs.m[k][j], MOD)) % MOD; return res; } LL fib(LL n, LL mod) { MOD = mod; if (n < 2) return n; n -= 2; Fmatrix res = Fmatrix(); Fmatrix sq = Fmatrix(); for (;n;n/=2) { if (n % 2) res = res * sq; sq = sq * sq; } return res.m[0][0]; } LL period[20]; LL solve(LL n, int len) { vector<LL> cand, new_cand; LL mod = 10; for (int i=0;i<60;i++) if (fib(i, 10) == n % 10LL) cand.PB(i); for (int i=1;i<len;i++) { mod *= 10LL; new_cand.clear(); for (LL c : cand) for (;c<period[i+1];c+=period[i]) if (fib(c, mod) == n % mod) new_cand.PB(c); cand.swap(new_cand); } return cand.empty() ? -1 : cand.back(); } void init() { period[1] = 60; period[2] = 300; period[3] = 1500; for (int i=4;i<20;i++) period[i] = period[i-1] * 10LL; } int main() { init(); char N[20]; LL n; scanf("%s", N); sscanf(N, "%lld", &n); LL res = solve(n, strlen(N)); if (res == -1) printf("NIE\n"); else printf("%lld\n", res); 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 | #include <unordered_map> #include <cstring> #include <cstdio> #include <vector> using namespace std; typedef long long LL; namespace mul { LL mul(LL a, LL b, LL mod) { LL res = 0; while (a) { if (a % 2) { res = res + b; if (res >= mod) res -= mod; } a /= 2; b = b + b; if (b >= mod) b -= mod; } return res; } }; #define PB push_back LL MOD; struct Fmatrix { LL m[2][2]; Fmatrix() { m[0][0] = m[0][1] = m[1][0] = 1; m[1][1] = 0; } }; Fmatrix operator*(const Fmatrix &lhs, const Fmatrix &rhs) { Fmatrix res; res.m[0][0] = res.m[0][1] = res.m[1][0] = res.m[1][1] = 0; for (int i=0;i<2;i++) for (int j=0;j<2;j++) for (int k=0;k<2;k++) res.m[i][j] = (res.m[i][j] + mul::mul(lhs.m[i][k], rhs.m[k][j], MOD)) % MOD; return res; } LL fib(LL n, LL mod) { MOD = mod; if (n < 2) return n; n -= 2; Fmatrix res = Fmatrix(); Fmatrix sq = Fmatrix(); for (;n;n/=2) { if (n % 2) res = res * sq; sq = sq * sq; } return res.m[0][0]; } LL period[20]; LL solve(LL n, int len) { vector<LL> cand, new_cand; LL mod = 10; for (int i=0;i<60;i++) if (fib(i, 10) == n % 10LL) cand.PB(i); for (int i=1;i<len;i++) { mod *= 10LL; new_cand.clear(); for (LL c : cand) for (;c<period[i+1];c+=period[i]) if (fib(c, mod) == n % mod) new_cand.PB(c); cand.swap(new_cand); } return cand.empty() ? -1 : cand.back(); } void init() { period[1] = 60; period[2] = 300; period[3] = 1500; for (int i=4;i<20;i++) period[i] = period[i-1] * 10LL; } int main() { init(); char N[20]; LL n; scanf("%s", N); sscanf(N, "%lld", &n); LL res = solve(n, strlen(N)); if (res == -1) printf("NIE\n"); else printf("%lld\n", res); return 0; } |