#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
using namespace std;
typedef unsigned long long ll;
#define pb push_back
#define si size()
const int maxn=19;
ll mul(ll a, ll b, ll m){
ll res=0;
while(b){
res+=a*(b%10);
res%=m;
a=(a*10)%m;
b/=10;
}
return res;
}
void matrixMul(ll a[2][2], ll b[2][2], ll m){
ll c[2][2];
for(int i=0;i<2;++i)
for(int j=0;j<2;++j){
c[i][j]=0;
for(int k=0;k<2;++k){
c[i][j]+=mul(a[i][k], b[k][j], m);
c[i][j]%=m;
}
}
for(int i=0;i<2;++i)
for(int j=0;j<2;++j)
a[i][j]=c[i][j];
}
ll fib(ll n, ll m){
ll a[2][2]={{1, 1}, {1, 0}};
ll c[2][2]={{1, 0}, {0, 1}};
while(n){
if(n&1)
matrixMul(c, a, m);
n>>=1;
matrixMul(a, a, m);
}
return c[1][0];
}
ll num(char *s){
ll n=0;
for(int i=0;s[i];++i)
n=n*10+s[i]-'0';
return n;
}
vector<ll> findProperFibNums(ll p[], ll q[], ll r, int n){
vector<ll> V;
ll a=0, b=1;
for(int i=0;i<p[n];++i){
if(a==r)
V.pb(i);
swap(a+=b, b);
b%=q[n];
}
return V;
}
int main()
{
ll p[maxn]={0, 60, 300, 1500};
ll q[maxn]={1};
for(int i=4;i<maxn;++i)
p[i]=p[i-1]*10;
for(int i=1;i<maxn;++i)
q[i]=q[i-1]*10;
char s[maxn];
int n;
ll r;
scanf("%s", s);
n=strlen(s);
r=num(s);
vector<ll> V=findProperFibNums(p, q, r%q[3], min(3, n));
for(int i=4;i<=n;++i){
vector<ll> Q;
for(int j=0;j<V.si;++j)
for(int k=0;k<10;++k)
if(fib(V[j]+p[i-1]*k, q[i])==r%q[i])
Q.pb(V[j]+p[i-1]*k);
V.clear();
V=Q;
}
if(V.empty())
printf("NIE");
else printf("%llu", V[0]+p[n]);
}
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 | #include <cstdio> #include <algorithm> #include <vector> #include <cstring> using namespace std; typedef unsigned long long ll; #define pb push_back #define si size() const int maxn=19; ll mul(ll a, ll b, ll m){ ll res=0; while(b){ res+=a*(b%10); res%=m; a=(a*10)%m; b/=10; } return res; } void matrixMul(ll a[2][2], ll b[2][2], ll m){ ll c[2][2]; for(int i=0;i<2;++i) for(int j=0;j<2;++j){ c[i][j]=0; for(int k=0;k<2;++k){ c[i][j]+=mul(a[i][k], b[k][j], m); c[i][j]%=m; } } for(int i=0;i<2;++i) for(int j=0;j<2;++j) a[i][j]=c[i][j]; } ll fib(ll n, ll m){ ll a[2][2]={{1, 1}, {1, 0}}; ll c[2][2]={{1, 0}, {0, 1}}; while(n){ if(n&1) matrixMul(c, a, m); n>>=1; matrixMul(a, a, m); } return c[1][0]; } ll num(char *s){ ll n=0; for(int i=0;s[i];++i) n=n*10+s[i]-'0'; return n; } vector<ll> findProperFibNums(ll p[], ll q[], ll r, int n){ vector<ll> V; ll a=0, b=1; for(int i=0;i<p[n];++i){ if(a==r) V.pb(i); swap(a+=b, b); b%=q[n]; } return V; } int main() { ll p[maxn]={0, 60, 300, 1500}; ll q[maxn]={1}; for(int i=4;i<maxn;++i) p[i]=p[i-1]*10; for(int i=1;i<maxn;++i) q[i]=q[i-1]*10; char s[maxn]; int n; ll r; scanf("%s", s); n=strlen(s); r=num(s); vector<ll> V=findProperFibNums(p, q, r%q[3], min(3, n)); for(int i=4;i<=n;++i){ vector<ll> Q; for(int j=0;j<V.si;++j) for(int k=0;k<10;++k) if(fib(V[j]+p[i-1]*k, q[i])==r%q[i]) Q.pb(V[j]+p[i-1]*k); V.clear(); V=Q; } if(V.empty()) printf("NIE"); else printf("%llu", V[0]+p[n]); } |
English