#include <algorithm> #include <cstdio> #include <cstdlib> #include <list> #include <map> #include <queue> #include <set> #include <stack> #include <vector> #include <cmath> #include <cstring> #include <string> #include <iostream> #include <complex> #include <sstream> #include <cassert> using namespace std; typedef long long LL; typedef unsigned long long ULL; typedef long double LD; typedef vector<int> VI; typedef pair<int,int> PII; #define REP(i,n) for(int i=0;i<(n);++i) #define SIZE(c) ((int)((c).size())) #define FOR(i,a,b) for (int i=(a); i<(b); ++i) #define FOREACH(i,x) for (__typeof((x).begin()) i=(x).begin(); i!=(x).end(); ++i) #define FORD(i,a,b) for (int i=(a)-1; i>=(b); --i) #define ALL(v) (v).begin(), (v).end() #define pb push_back #define mp make_pair #define st first #define nd second LL p10[30]; LL pisano[30]; char C[30]; vector<LL> candidates[30]; LL mul(LL a, LL b) { LL a0 = a % p10[9], a1 = a / p10[9]; LL b0 = b % p10[9], b1 = b / p10[9]; LL res = a0 * b0; res += ((a1 * b0 + a0 * b1) % p10[9]) * p10[9]; return res % p10[18]; } map<LL, LL> F; LL fib(LL N) { if (N < 3) return min(N, 1LL); if (F.find(N) != F.end()) return F[N]; LL K = N / 2; if (N == 2 * K) { return F[2*K] = (mul(fib(K+1), fib(K+1)) - mul(fib(K-1), fib(K-1)) + p10[18]) % p10[18]; } else { return F[2*K+1] = (mul(fib(K+1), fib(K+1)) + mul(fib(K), fib(K)) + p10[18]) % p10[18]; } } int main() { p10[0] = 1; FOR(i,1,20) p10[i] = p10[i-1] * 10; pisano[0] = 1; pisano[1] = 60; pisano[2] = 300; pisano[3] = 1500; FOR(i,4,20) pisano[i] = pisano[i-1] * 10; scanf("%s", C); int N = strlen(C); reverse(C, C + N); REP(i,N) C[i] -= '0'; candidates[0].pb(0); LL remainder = 0; FOR(i,1,N+1) { remainder += p10[i-1] * C[i-1]; FOREACH(it, candidates[i-1]) { for (LL c = *it; c < pisano[i]; c += pisano[i-1]) { if (fib(c) % p10[i] == remainder) candidates[i].pb(c); } } } if (candidates[N].empty()) { printf("NIE\n"); } else { printf("%lld\n", pisano[18] + candidates[N][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 | #include <algorithm> #include <cstdio> #include <cstdlib> #include <list> #include <map> #include <queue> #include <set> #include <stack> #include <vector> #include <cmath> #include <cstring> #include <string> #include <iostream> #include <complex> #include <sstream> #include <cassert> using namespace std; typedef long long LL; typedef unsigned long long ULL; typedef long double LD; typedef vector<int> VI; typedef pair<int,int> PII; #define REP(i,n) for(int i=0;i<(n);++i) #define SIZE(c) ((int)((c).size())) #define FOR(i,a,b) for (int i=(a); i<(b); ++i) #define FOREACH(i,x) for (__typeof((x).begin()) i=(x).begin(); i!=(x).end(); ++i) #define FORD(i,a,b) for (int i=(a)-1; i>=(b); --i) #define ALL(v) (v).begin(), (v).end() #define pb push_back #define mp make_pair #define st first #define nd second LL p10[30]; LL pisano[30]; char C[30]; vector<LL> candidates[30]; LL mul(LL a, LL b) { LL a0 = a % p10[9], a1 = a / p10[9]; LL b0 = b % p10[9], b1 = b / p10[9]; LL res = a0 * b0; res += ((a1 * b0 + a0 * b1) % p10[9]) * p10[9]; return res % p10[18]; } map<LL, LL> F; LL fib(LL N) { if (N < 3) return min(N, 1LL); if (F.find(N) != F.end()) return F[N]; LL K = N / 2; if (N == 2 * K) { return F[2*K] = (mul(fib(K+1), fib(K+1)) - mul(fib(K-1), fib(K-1)) + p10[18]) % p10[18]; } else { return F[2*K+1] = (mul(fib(K+1), fib(K+1)) + mul(fib(K), fib(K)) + p10[18]) % p10[18]; } } int main() { p10[0] = 1; FOR(i,1,20) p10[i] = p10[i-1] * 10; pisano[0] = 1; pisano[1] = 60; pisano[2] = 300; pisano[3] = 1500; FOR(i,4,20) pisano[i] = pisano[i-1] * 10; scanf("%s", C); int N = strlen(C); reverse(C, C + N); REP(i,N) C[i] -= '0'; candidates[0].pb(0); LL remainder = 0; FOR(i,1,N+1) { remainder += p10[i-1] * C[i-1]; FOREACH(it, candidates[i-1]) { for (LL c = *it; c < pisano[i]; c += pisano[i-1]) { if (fib(c) % p10[i] == remainder) candidates[i].pb(c); } } } if (candidates[N].empty()) { printf("NIE\n"); } else { printf("%lld\n", pisano[18] + candidates[N][0]); } } |