#include<bits/stdc++.h>
using namespace std;
vector<long long> dobre, dobre2;
char s[20];
long long m1[2][2], m2[2][2], m3[2][2];
long long mno(long long a, long long b, long long mod)
{
long long x=a, wyn=0;
x%=mod;
while(b>0)
{
if(b%2==1)
wyn+=x;
x+=x;
if(x>=mod)
x-=mod;
if(wyn>=mod)
wyn-=mod;
b/=2;
}
return wyn;
}
long long fib(long long n, long long mod)
{
if(n==0)
return 0;
if(n==1)
return 1;
n--;
m1[0][0]=1;
m1[0][1]=1;
m1[1][0]=1;
m1[1][1]=0;
m2[0][0]=1;
m2[0][1]=1;
m2[1][0]=1;
m2[1][1]=0;
while(n>0)
{
if(n&1==1)
{
m3[0][0]=0;
m3[0][1]=0;
m3[1][0]=0;
m3[1][1]=0;
for(int i=0; i<2; i++)
for(int j=0; j<2; j++)
for(int k=0; k<2; k++)
m3[i][j]+=mno(m1[i][k], m2[k][j], mod);
for(int i=0; i<2; i++)
for(int j=0; j<2; j++)
m1[i][j]=(m3[i][j])%mod;
}
m3[0][0]=0;
m3[0][1]=0;
m3[1][0]=0;
m3[1][1]=0;
for(int i=0; i<2; i++)
for(int j=0; j<2; j++)
for(int k=0; k<2; k++)
m3[i][j]+=mno(m2[i][k], m2[k][j], mod);
for(int i=0; i<2; i++)
for(int j=0; j<2; j++)
m2[i][j]=(m3[i][j])%mod;
n/=2;
}
return m1[0][1];
}
int main()
{
scanf("%s", s);
int n=0;
while(s[n]!=0)
n++;
long long dl=1, mod=1, li=0;
dobre.push_back(0);
for(int i=n-1; i>=0; i--){
li=li+mod*(long long)(s[i]-48);
mod*=10;
long long nd=0;
while(!((fib(nd+1, mod)==1) && (fib(nd+2, mod)==1) && nd!=0))
{
for(int j=0; j<dobre.size(); j++)
if(fib(dobre[j]+nd, mod)==li)
{
dobre2.push_back(dobre[j]+nd);
//printf("%d %lld\n", i, dobre[j]+nd);
}
nd+=dl;
}
dl=nd;
dobre=dobre2;
dobre2.clear();
if(dobre.size()==0)
break;
}
if(dobre.size()==0)
printf("NIE\n");
else
printf("%lld\n", dobre[0]+dl);
}
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 | #include<bits/stdc++.h> using namespace std; vector<long long> dobre, dobre2; char s[20]; long long m1[2][2], m2[2][2], m3[2][2]; long long mno(long long a, long long b, long long mod) { long long x=a, wyn=0; x%=mod; while(b>0) { if(b%2==1) wyn+=x; x+=x; if(x>=mod) x-=mod; if(wyn>=mod) wyn-=mod; b/=2; } return wyn; } long long fib(long long n, long long mod) { if(n==0) return 0; if(n==1) return 1; n--; m1[0][0]=1; m1[0][1]=1; m1[1][0]=1; m1[1][1]=0; m2[0][0]=1; m2[0][1]=1; m2[1][0]=1; m2[1][1]=0; while(n>0) { if(n&1==1) { m3[0][0]=0; m3[0][1]=0; m3[1][0]=0; m3[1][1]=0; for(int i=0; i<2; i++) for(int j=0; j<2; j++) for(int k=0; k<2; k++) m3[i][j]+=mno(m1[i][k], m2[k][j], mod); for(int i=0; i<2; i++) for(int j=0; j<2; j++) m1[i][j]=(m3[i][j])%mod; } m3[0][0]=0; m3[0][1]=0; m3[1][0]=0; m3[1][1]=0; for(int i=0; i<2; i++) for(int j=0; j<2; j++) for(int k=0; k<2; k++) m3[i][j]+=mno(m2[i][k], m2[k][j], mod); for(int i=0; i<2; i++) for(int j=0; j<2; j++) m2[i][j]=(m3[i][j])%mod; n/=2; } return m1[0][1]; } int main() { scanf("%s", s); int n=0; while(s[n]!=0) n++; long long dl=1, mod=1, li=0; dobre.push_back(0); for(int i=n-1; i>=0; i--){ li=li+mod*(long long)(s[i]-48); mod*=10; long long nd=0; while(!((fib(nd+1, mod)==1) && (fib(nd+2, mod)==1) && nd!=0)) { for(int j=0; j<dobre.size(); j++) if(fib(dobre[j]+nd, mod)==li) { dobre2.push_back(dobre[j]+nd); //printf("%d %lld\n", i, dobre[j]+nd); } nd+=dl; } dl=nd; dobre=dobre2; dobre2.clear(); if(dobre.size()==0) break; } if(dobre.size()==0) printf("NIE\n"); else printf("%lld\n", dobre[0]+dl); } |
English