#include <iostream>
#include <vector>
#include <map>
#include <algorithm>
using namespace std;
typedef pair<long long, long long> KEY;
typedef map<KEY, long long> AUG;
AUG augm;
long long ffib(long long n, long long mod){
if((n==0)||(n==1)) return n;
AUG::iterator i = augm.find(KEY(n,mod));
if(i!=augm.end()) return (*i).second;
long long res;
if((n+1)%2){
long long nn = ffib(n/2, mod);
long long n_minus_1 = ffib(n/2-1, mod);
res = (2*n_minus_1+nn)%mod;
res = (res*nn)%mod;
} else {
long long nn = ffib(n/2, mod);
long long n_plus_1 = ffib(n/2+1, mod);
res = (nn*nn)%mod;
res += (n_plus_1*n_plus_1)%mod;
res = res%mod;
}
augm[KEY(n,mod)]=res;
return res;
}
long long find_some(long long beg, long long step, long long limit, long long mod, long long what){
long long j;
for(long long i=0; (j=beg+i*step)<limit; i++){
long long fb=ffib(j,mod);
if(fb==what%mod) return j;
}
return limit;
}
vector<long long> find_all(long long beg, long long step, long long limit, long long mod, long long what){
vector<long long> v;
long long fnd;
while((fnd=find_some(beg, step, limit, mod, what))<limit){
v.push_back(fnd);
beg=fnd+step;
}
return v;
}
struct _check{
long long pw;
long long nm;
_check(long long p, long long n):pw(p), nm(n){};
bool operator()(long long a){
return ffib(a,pw)==nm%pw;
}
};
long long logpw(long long pw5, long long coeff){
return 4*pw5/5;
}
long long check(long long number){
long long power = 1;
long long uper = 10;
while(number>uper){power++; uper*=10;}
long long pw5=5;
long long delim=6;
long long beg=1;
long long pw2=2;
long long step=1;
vector<long long> sfar;
sfar.push_back(beg);
for(long long pw=1; pw<=power; pw++){
// find period on this level
long long perd = find_some(beg,step,beg+delim, pw5, 0);
long long coeff=ffib(perd-1, pw5);
long long tms = logpw(pw5, coeff);
long long delim=tms*perd+1;
vector<long long> temp;
for(vector<long long>::iterator i = sfar.begin(); i!=sfar.end(); i++){
vector<long long> found = find_all(*i, step, delim, pw5, number);
for(vector<long long>::iterator j = found.begin(); j!=found.end(); j++){
temp.push_back(*j);
}
}
if(temp.empty()) return -1;
sfar.erase(sfar.begin(), sfar.end());
for(vector<long long>::iterator i = temp.begin(); i!=temp.end(); i++){
if(_check(pw2, number)(*i)) sfar.push_back(*i);
}
if(sfar.empty()) return -1;
beg = perd;
pw2 *= 2;
pw5 *= 5;
step = perd;
}
if(sfar.empty()) return -1;
return sfar[0];
}
void myfunction(long long l){
cout<<" "<<l<<" ";
}
int main(){
long long n;
cin>>n;
long long res = check(n);
if(res<0) cout<<"NIE"; else cout<<res;
}
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 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | #include <iostream> #include <vector> #include <map> #include <algorithm> using namespace std; typedef pair<long long, long long> KEY; typedef map<KEY, long long> AUG; AUG augm; long long ffib(long long n, long long mod){ if((n==0)||(n==1)) return n; AUG::iterator i = augm.find(KEY(n,mod)); if(i!=augm.end()) return (*i).second; long long res; if((n+1)%2){ long long nn = ffib(n/2, mod); long long n_minus_1 = ffib(n/2-1, mod); res = (2*n_minus_1+nn)%mod; res = (res*nn)%mod; } else { long long nn = ffib(n/2, mod); long long n_plus_1 = ffib(n/2+1, mod); res = (nn*nn)%mod; res += (n_plus_1*n_plus_1)%mod; res = res%mod; } augm[KEY(n,mod)]=res; return res; } long long find_some(long long beg, long long step, long long limit, long long mod, long long what){ long long j; for(long long i=0; (j=beg+i*step)<limit; i++){ long long fb=ffib(j,mod); if(fb==what%mod) return j; } return limit; } vector<long long> find_all(long long beg, long long step, long long limit, long long mod, long long what){ vector<long long> v; long long fnd; while((fnd=find_some(beg, step, limit, mod, what))<limit){ v.push_back(fnd); beg=fnd+step; } return v; } struct _check{ long long pw; long long nm; _check(long long p, long long n):pw(p), nm(n){}; bool operator()(long long a){ return ffib(a,pw)==nm%pw; } }; long long logpw(long long pw5, long long coeff){ return 4*pw5/5; } long long check(long long number){ long long power = 1; long long uper = 10; while(number>uper){power++; uper*=10;} long long pw5=5; long long delim=6; long long beg=1; long long pw2=2; long long step=1; vector<long long> sfar; sfar.push_back(beg); for(long long pw=1; pw<=power; pw++){ // find period on this level long long perd = find_some(beg,step,beg+delim, pw5, 0); long long coeff=ffib(perd-1, pw5); long long tms = logpw(pw5, coeff); long long delim=tms*perd+1; vector<long long> temp; for(vector<long long>::iterator i = sfar.begin(); i!=sfar.end(); i++){ vector<long long> found = find_all(*i, step, delim, pw5, number); for(vector<long long>::iterator j = found.begin(); j!=found.end(); j++){ temp.push_back(*j); } } if(temp.empty()) return -1; sfar.erase(sfar.begin(), sfar.end()); for(vector<long long>::iterator i = temp.begin(); i!=temp.end(); i++){ if(_check(pw2, number)(*i)) sfar.push_back(*i); } if(sfar.empty()) return -1; beg = perd; pw2 *= 2; pw5 *= 5; step = perd; } if(sfar.empty()) return -1; return sfar[0]; } void myfunction(long long l){ cout<<" "<<l<<" "; } int main(){ long long n; cin>>n; long long res = check(n); if(res<0) cout<<"NIE"; else cout<<res; } |
English