#include <iostream> #include <cstring> #include <algorithm> #include <vector> #include <set> #include <utility> #include <queue> #include <map> using namespace std; typedef long long i64; typedef unsigned long long u64; int len; char str[100]; int current=0, _next=1; vector<u64> potential[2]; u64 last_digits(int i) { u64 res=0; for (int j=i-1; j>=0; j--) res = res*10+u64(str[len-j-1] - '0'); return res; } map<u64,u64> F; const u64 bilion = 1000000000LL; u64 fib(u64 n) { //F(2n-1)=F(n-1)^2+F(n)^2 //F(2n)=(2F(n-1)+F(n))*F(n) if (n<=1) return n; auto i = F.find(n); if (i!=F.end()) return i->second; u64 a,b, a1, a2, b1, b2, res; if (n%2 == 1) { a = fib(n/2); a1 = a % bilion; a2 = a/bilion; b = fib(n/2+1); b1 = b % bilion; b2 = b/bilion; res= (a1*a1+b1*b1 + 2*((a1*a2)%bilion)*bilion + 2*((b1*b2)%bilion)*bilion)%(bilion*bilion); } else { a = fib(n/2-1); a1 = a % bilion; a2 = a/bilion; b = fib(n/2); b1 = b % bilion; b2 = b/bilion; res= (2*a1*b1+b1*b1 + 2*((a1*b2)%bilion)*bilion + 2*((a2*b1)%bilion)*bilion + 2*((b1*b2)%bilion)*bilion)%(bilion*bilion); } F[n]=res; return res; } u64 roundsa[19] = {60,5,5,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10}; u64 roundsb[18] = {60}; int main() { std::ios::sync_with_stdio(false); for (int i=1; i<18; i++) roundsb[i] = roundsb[i-1]*roundsa[i]; cin>>str; len=strlen(str); for (int i=0; i<=59; i++) { potential[current].push_back(i); } u64 cur_mod=10; for (int round=0; round<len; round++, cur_mod*=10) { u64 last_digs = last_digits(round+1); for (auto i : potential[current]) { auto fib_mod = fib(i)%cur_mod; if (fib_mod == last_digs){ for (int j=0; j<roundsa[round+1]; j++) potential[_next].push_back(roundsb[round]*j+i); } } swap(current,_next); potential[_next].clear(); } // for (int z = 0; z<300; z++) cout<<z<<": "<<fib(z)<<endl; // cout<<endl; // cout<<fib(1000000000000000000LL)<<endl; if (potential[current].size() == 0) { cout<<"NIE"<<endl; } else { // for (auto i : potential[current]) cout<<i<<' '; cout<<endl; cout<<potential[current][0]<<endl; } 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 | #include <iostream> #include <cstring> #include <algorithm> #include <vector> #include <set> #include <utility> #include <queue> #include <map> using namespace std; typedef long long i64; typedef unsigned long long u64; int len; char str[100]; int current=0, _next=1; vector<u64> potential[2]; u64 last_digits(int i) { u64 res=0; for (int j=i-1; j>=0; j--) res = res*10+u64(str[len-j-1] - '0'); return res; } map<u64,u64> F; const u64 bilion = 1000000000LL; u64 fib(u64 n) { //F(2n-1)=F(n-1)^2+F(n)^2 //F(2n)=(2F(n-1)+F(n))*F(n) if (n<=1) return n; auto i = F.find(n); if (i!=F.end()) return i->second; u64 a,b, a1, a2, b1, b2, res; if (n%2 == 1) { a = fib(n/2); a1 = a % bilion; a2 = a/bilion; b = fib(n/2+1); b1 = b % bilion; b2 = b/bilion; res= (a1*a1+b1*b1 + 2*((a1*a2)%bilion)*bilion + 2*((b1*b2)%bilion)*bilion)%(bilion*bilion); } else { a = fib(n/2-1); a1 = a % bilion; a2 = a/bilion; b = fib(n/2); b1 = b % bilion; b2 = b/bilion; res= (2*a1*b1+b1*b1 + 2*((a1*b2)%bilion)*bilion + 2*((a2*b1)%bilion)*bilion + 2*((b1*b2)%bilion)*bilion)%(bilion*bilion); } F[n]=res; return res; } u64 roundsa[19] = {60,5,5,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10}; u64 roundsb[18] = {60}; int main() { std::ios::sync_with_stdio(false); for (int i=1; i<18; i++) roundsb[i] = roundsb[i-1]*roundsa[i]; cin>>str; len=strlen(str); for (int i=0; i<=59; i++) { potential[current].push_back(i); } u64 cur_mod=10; for (int round=0; round<len; round++, cur_mod*=10) { u64 last_digs = last_digits(round+1); for (auto i : potential[current]) { auto fib_mod = fib(i)%cur_mod; if (fib_mod == last_digs){ for (int j=0; j<roundsa[round+1]; j++) potential[_next].push_back(roundsb[round]*j+i); } } swap(current,_next); potential[_next].clear(); } // for (int z = 0; z<300; z++) cout<<z<<": "<<fib(z)<<endl; // cout<<endl; // cout<<fib(1000000000000000000LL)<<endl; if (potential[current].size() == 0) { cout<<"NIE"<<endl; } else { // for (auto i : potential[current]) cout<<i<<' '; cout<<endl; cout<<potential[current][0]<<endl; } return 0; } |