#include <cstdio> #include <cstring> long long pi[19]; char c[20], len; int d[20]; long long pw10[20]; long long mult(long long a, long long b, long long mod) { long long res = 0; while (a) { if (a & 1) { res = (res + b) % mod; } b = (b << 1) % mod; a >>= 1; } return res; } struct Matrix { long long t[2][2]; }; Matrix getMat(long long a00, long long a01, long long a10, long long a11) { Matrix res; res.t[0][0] = a00; res.t[0][1] = a01; res.t[1][0] = a10; res.t[1][1] = a11; return res; } Matrix matrixMult(Matrix A, Matrix B, long long mod) { Matrix R = getMat(0, 0, 0, 0); for (int i = 0; i < 2; ++i) { for (int j = 0; j < 2; ++j) { for (int k = 0; k < 2; ++k) { R.t[i][j] = (R.t[i][j] + mult(A.t[i][k], B.t[k][j], mod)) % mod; } } } return R; } long long fib(long long n, long long mod) { Matrix A = getMat(1, 1, 1, 0); Matrix R = getMat(1, 0, 0, 1); while (n) { if (n & 1) { R = matrixMult(R, A, mod); } A = matrixMult(A, A, mod); n >>= 1; } return R.t[1][0]; } int dig(long long a, int pos) { return (a / pw10[pos]) % 10; } void go(long long n, int pos) { // printf("go %lld %d\n", n, pos); if (pos == len-1) { if (n < 100) { n += pi[17]; } printf("%lld\n", n); throw 0; } long long i = n; int limit = pi[pos+1] / pi[pos]; for (int j = 0; j < limit; ++j, i += pi[pos]) { // printf("sprawdzam %lld %d\n", i, pos); // printf("licze f %lld modulo %lld\n", i, pw10[pos+2]); long long fb = fib(i, pw10[pos+2]); int dg = dig(fb, pos+1); // printf("fb = %lld dg = %d\n", fb, dg); if (dg == d[pos+1]) { go(i, pos+1); } } } int main() { pi[0] = 60; pi[1] = 300; pi[2] = 1500; for (int i = 3; i < 18; ++i) { pi[i] = 10*pi[i-1]; } pw10[0] = 1; for (int i = 1; i <= 18; ++i) { pw10[i] = 10*pw10[i-1]; } scanf("%s", c); len = strlen(c); for (int i = len-1; i >= 0; --i) { d[len - 1 - i] = c[i] - '0'; } try { for (int i = 0; i < pi[0]; ++i) { if (fib(i, 10) == d[0]) { go(i, 0); } } } catch(int) { return 0; } printf("NIE\n"); 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 106 107 108 109 110 111 112 113 114 | #include <cstdio> #include <cstring> long long pi[19]; char c[20], len; int d[20]; long long pw10[20]; long long mult(long long a, long long b, long long mod) { long long res = 0; while (a) { if (a & 1) { res = (res + b) % mod; } b = (b << 1) % mod; a >>= 1; } return res; } struct Matrix { long long t[2][2]; }; Matrix getMat(long long a00, long long a01, long long a10, long long a11) { Matrix res; res.t[0][0] = a00; res.t[0][1] = a01; res.t[1][0] = a10; res.t[1][1] = a11; return res; } Matrix matrixMult(Matrix A, Matrix B, long long mod) { Matrix R = getMat(0, 0, 0, 0); for (int i = 0; i < 2; ++i) { for (int j = 0; j < 2; ++j) { for (int k = 0; k < 2; ++k) { R.t[i][j] = (R.t[i][j] + mult(A.t[i][k], B.t[k][j], mod)) % mod; } } } return R; } long long fib(long long n, long long mod) { Matrix A = getMat(1, 1, 1, 0); Matrix R = getMat(1, 0, 0, 1); while (n) { if (n & 1) { R = matrixMult(R, A, mod); } A = matrixMult(A, A, mod); n >>= 1; } return R.t[1][0]; } int dig(long long a, int pos) { return (a / pw10[pos]) % 10; } void go(long long n, int pos) { // printf("go %lld %d\n", n, pos); if (pos == len-1) { if (n < 100) { n += pi[17]; } printf("%lld\n", n); throw 0; } long long i = n; int limit = pi[pos+1] / pi[pos]; for (int j = 0; j < limit; ++j, i += pi[pos]) { // printf("sprawdzam %lld %d\n", i, pos); // printf("licze f %lld modulo %lld\n", i, pw10[pos+2]); long long fb = fib(i, pw10[pos+2]); int dg = dig(fb, pos+1); // printf("fb = %lld dg = %d\n", fb, dg); if (dg == d[pos+1]) { go(i, pos+1); } } } int main() { pi[0] = 60; pi[1] = 300; pi[2] = 1500; for (int i = 3; i < 18; ++i) { pi[i] = 10*pi[i-1]; } pw10[0] = 1; for (int i = 1; i <= 18; ++i) { pw10[i] = 10*pw10[i-1]; } scanf("%s", c); len = strlen(c); for (int i = len-1; i >= 0; --i) { d[len - 1 - i] = c[i] - '0'; } try { for (int i = 0; i < pi[0]; ++i) { if (fib(i, 10) == d[0]) { go(i, 0); } } } catch(int) { return 0; } printf("NIE\n"); return 0; } |