#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]); } } |
English