#include <bits/stdc++.h> using namespace std; const int N = 19; long long cycleLength[N + 5]; long long M; char input[N]; inline long long add(long long a, long long b) { if (a + b >= M) { return a + b - M; } return a + b; } long long mul(long long a, long long b) { if (b == 0) { return 0; } if (b == 1) { return a; } if (a > b) { swap(a, b); } if (b <= 1e9) { return a * b % M; } long long ret = mul(a, b / 2); return add(add(ret, ret), (b % 2? a: 0)); } inline void multiply(long long &leftTop, long long &rightTop, long long &leftBottom, long long &rightBottom, long long &leftTopB, long long &rightTopB, long long &leftBottomB, long long &rightBottomB) { long long retA = add(mul(leftTop, leftTopB), mul(rightTop, leftBottomB)); long long retB = add(mul(leftTop, rightTopB), mul(rightTop, rightBottomB)); long long retC = add(mul(leftBottom, leftTopB), mul(rightBottom, leftBottomB)); long long retD = add(mul(leftBottom, rightTopB), mul(rightBottom, rightBottomB)); leftTop = retA; rightTop = retB; leftBottom = retC; rightBottom = retD; } long long fastFib(long long n) { long long leftTop = 1; long long rightTop = 1; long long leftBottom = 1; long long rightBottom = 0; long long ansLeftTop = 1; long long ansRightTop = 0; long long ansLeftBottom = 1; long long ansRightBottom = 0; while(n >= 1) { if (n % 2 == 1) { multiply(ansLeftTop, ansRightTop, ansLeftBottom, ansRightBottom, leftTop, rightTop, leftBottom, rightBottom); } multiply(leftTop, rightTop, leftBottom, rightBottom, leftTop, rightTop, leftBottom, rightBottom); n /= 2; } return ansRightTop; } int main() { cycleLength[0] = 1; cycleLength[1] = 60; cycleLength[2] = 300; cycleLength[3] = 1500; for (int i = 4; i < N; i++) { cycleLength[i] = cycleLength[i - 1] * 10; } scanf("%s", &input[1]); int moduloExp = strlen(input + 1); long long searchingValue = atoll(input + 1); vector<long long> goodValues; goodValues.push_back(0); M = 10; for (int i = 1; i <= moduloExp; i++) { vector<long long> newGoodValues; long long searchingValueMod = searchingValue % M; for (int j = 0; j < goodValues.size(); j++) { long long x = goodValues[j]; while (x < cycleLength[i]) { if (fastFib(x) == searchingValueMod) { newGoodValues.push_back(x); } x += cycleLength[i - 1]; } } goodValues = newGoodValues; M *= 10; sort(goodValues.begin(), goodValues.end()); } if (goodValues.size() == 0) { printf("NIE\n"); } else { printf("%lld\n", goodValues[0] + 1500000000000000000LL); } 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 115 116 117 118 119 120 121 122 | #include <bits/stdc++.h> using namespace std; const int N = 19; long long cycleLength[N + 5]; long long M; char input[N]; inline long long add(long long a, long long b) { if (a + b >= M) { return a + b - M; } return a + b; } long long mul(long long a, long long b) { if (b == 0) { return 0; } if (b == 1) { return a; } if (a > b) { swap(a, b); } if (b <= 1e9) { return a * b % M; } long long ret = mul(a, b / 2); return add(add(ret, ret), (b % 2? a: 0)); } inline void multiply(long long &leftTop, long long &rightTop, long long &leftBottom, long long &rightBottom, long long &leftTopB, long long &rightTopB, long long &leftBottomB, long long &rightBottomB) { long long retA = add(mul(leftTop, leftTopB), mul(rightTop, leftBottomB)); long long retB = add(mul(leftTop, rightTopB), mul(rightTop, rightBottomB)); long long retC = add(mul(leftBottom, leftTopB), mul(rightBottom, leftBottomB)); long long retD = add(mul(leftBottom, rightTopB), mul(rightBottom, rightBottomB)); leftTop = retA; rightTop = retB; leftBottom = retC; rightBottom = retD; } long long fastFib(long long n) { long long leftTop = 1; long long rightTop = 1; long long leftBottom = 1; long long rightBottom = 0; long long ansLeftTop = 1; long long ansRightTop = 0; long long ansLeftBottom = 1; long long ansRightBottom = 0; while(n >= 1) { if (n % 2 == 1) { multiply(ansLeftTop, ansRightTop, ansLeftBottom, ansRightBottom, leftTop, rightTop, leftBottom, rightBottom); } multiply(leftTop, rightTop, leftBottom, rightBottom, leftTop, rightTop, leftBottom, rightBottom); n /= 2; } return ansRightTop; } int main() { cycleLength[0] = 1; cycleLength[1] = 60; cycleLength[2] = 300; cycleLength[3] = 1500; for (int i = 4; i < N; i++) { cycleLength[i] = cycleLength[i - 1] * 10; } scanf("%s", &input[1]); int moduloExp = strlen(input + 1); long long searchingValue = atoll(input + 1); vector<long long> goodValues; goodValues.push_back(0); M = 10; for (int i = 1; i <= moduloExp; i++) { vector<long long> newGoodValues; long long searchingValueMod = searchingValue % M; for (int j = 0; j < goodValues.size(); j++) { long long x = goodValues[j]; while (x < cycleLength[i]) { if (fastFib(x) == searchingValueMod) { newGoodValues.push_back(x); } x += cycleLength[i - 1]; } } goodValues = newGoodValues; M *= 10; sort(goodValues.begin(), goodValues.end()); } if (goodValues.size() == 0) { printf("NIE\n"); } else { printf("%lld\n", goodValues[0] + 1500000000000000000LL); } return 0; } |