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