#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;
typedef long long BigInt;
BigInt addmod( BigInt x, BigInt y, BigInt m )
{
x %= m;
y %= m;
BigInt sum = x-m+y; // -m <= sum < m-1
return sum < 0 ? sum + m : sum;
}
BigInt timesmod( BigInt x, BigInt y, BigInt m )
{
x %= m;
y %= m;
BigInt a = x < y ? x : y; // min
BigInt b = x < y ? y : x; // max
BigInt product = 0;
for (; a != 0; a >>= 1, b = addmod(b,b,m) )
if (a&1) product = addmod(product,b,m);
return product;
}
void multiply(unsigned long long int F[2][2], unsigned long long int M[2][2], unsigned long long int mod);
void power(unsigned long long int F[2][2], unsigned long long int n, unsigned long long int mod);
/* function that returns nth Fibonacci number */
unsigned long long int fib(unsigned long long int n, unsigned long long int mod)
{
unsigned long long int F[2][2] = {{1,1},{1,0}};
if (n == 0)
return 0;
power(F, n-1, mod);
return F[0][0];
}
/* Optimized version of power() in method 4 */
void power(unsigned long long int F[2][2], unsigned long long int n, unsigned long long int mod)
{
if( n == 0 || n == 1)
return;
unsigned long long int M[2][2] = {{1,1},{1,0}};
power(F, n/2, mod);
multiply(F, F, mod);
if (n%2 != 0)
multiply(F, M, mod);
}
void multiply(unsigned long long int F[2][2], unsigned long long int M[2][2], unsigned long long int mod)
{
unsigned long long int x = timesmod(F[0][0],M[0][0],mod) + timesmod(F[0][1], M[1][0], mod);
unsigned long long int y = timesmod(F[0][0],M[0][1],mod) + timesmod(F[0][1], M[1][1], mod);
unsigned long long int z = timesmod(F[1][0],M[0][0],mod) + timesmod(F[1][1] ,M[1][0], mod);
unsigned long long int w = timesmod(F[1][0],M[0][1],mod) + timesmod(F[1][1], M[1][1], mod);
F[0][0] = x%mod;
F[0][1] = y%mod;
F[1][0] = z%mod;
F[1][1] = w%mod;
}
/* Driver program to test above function */
unsigned long long int nastepny_przeskok(unsigned long long int p){
if (p==1) return 60;
if (p==300) return 1500;
if (p==60) return 300;
return p*10;
}
unsigned long long int czy_da_sie(unsigned long long int do_znalezienia,
unsigned long long int do_dodania,
unsigned long long int n,
unsigned long long int przeskok,
unsigned long long int modulo,
unsigned long long int cel){
if(fib(n, 1000000000000000000)*10 <modulo) return 0;
if(modulo==cel) return n;
do_znalezienia+=(do_dodania%10)*modulo;
modulo*=10;
do_dodania-=do_dodania%10;
do_dodania/=10;
unsigned long long int zakres = nastepny_przeskok(przeskok)/przeskok *2;
unsigned long long int wynik;
for(unsigned int i=0; i <= zakres ; i++){
if(fib(n, modulo)==do_znalezienia){
//cout << "znaleziono " << fib(n, modulo) << " " << do_znalezienia<< " " << n << endl;
//getch();
wynik=czy_da_sie( do_znalezienia, do_dodania, n, nastepny_przeskok(przeskok), modulo, cel);
if(wynik) return wynik;
}
n+=przeskok;
}
return 0;
}
int main()
{
unsigned long long int c, wynik, cel;
string s;
cel=1;
cin >> s;
c=s.length();
while(c--) cel*=10;
c=atoll(s.c_str());
wynik=czy_da_sie(0, c, 1, 1, 1, cel);
if(wynik) cout << wynik;
else cout << "NIE";
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 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 118 119 | #include <iostream> #include <string> #include <cstdlib> using namespace std; typedef long long BigInt; BigInt addmod( BigInt x, BigInt y, BigInt m ) { x %= m; y %= m; BigInt sum = x-m+y; // -m <= sum < m-1 return sum < 0 ? sum + m : sum; } BigInt timesmod( BigInt x, BigInt y, BigInt m ) { x %= m; y %= m; BigInt a = x < y ? x : y; // min BigInt b = x < y ? y : x; // max BigInt product = 0; for (; a != 0; a >>= 1, b = addmod(b,b,m) ) if (a&1) product = addmod(product,b,m); return product; } void multiply(unsigned long long int F[2][2], unsigned long long int M[2][2], unsigned long long int mod); void power(unsigned long long int F[2][2], unsigned long long int n, unsigned long long int mod); /* function that returns nth Fibonacci number */ unsigned long long int fib(unsigned long long int n, unsigned long long int mod) { unsigned long long int F[2][2] = {{1,1},{1,0}}; if (n == 0) return 0; power(F, n-1, mod); return F[0][0]; } /* Optimized version of power() in method 4 */ void power(unsigned long long int F[2][2], unsigned long long int n, unsigned long long int mod) { if( n == 0 || n == 1) return; unsigned long long int M[2][2] = {{1,1},{1,0}}; power(F, n/2, mod); multiply(F, F, mod); if (n%2 != 0) multiply(F, M, mod); } void multiply(unsigned long long int F[2][2], unsigned long long int M[2][2], unsigned long long int mod) { unsigned long long int x = timesmod(F[0][0],M[0][0],mod) + timesmod(F[0][1], M[1][0], mod); unsigned long long int y = timesmod(F[0][0],M[0][1],mod) + timesmod(F[0][1], M[1][1], mod); unsigned long long int z = timesmod(F[1][0],M[0][0],mod) + timesmod(F[1][1] ,M[1][0], mod); unsigned long long int w = timesmod(F[1][0],M[0][1],mod) + timesmod(F[1][1], M[1][1], mod); F[0][0] = x%mod; F[0][1] = y%mod; F[1][0] = z%mod; F[1][1] = w%mod; } /* Driver program to test above function */ unsigned long long int nastepny_przeskok(unsigned long long int p){ if (p==1) return 60; if (p==300) return 1500; if (p==60) return 300; return p*10; } unsigned long long int czy_da_sie(unsigned long long int do_znalezienia, unsigned long long int do_dodania, unsigned long long int n, unsigned long long int przeskok, unsigned long long int modulo, unsigned long long int cel){ if(fib(n, 1000000000000000000)*10 <modulo) return 0; if(modulo==cel) return n; do_znalezienia+=(do_dodania%10)*modulo; modulo*=10; do_dodania-=do_dodania%10; do_dodania/=10; unsigned long long int zakres = nastepny_przeskok(przeskok)/przeskok *2; unsigned long long int wynik; for(unsigned int i=0; i <= zakres ; i++){ if(fib(n, modulo)==do_znalezienia){ //cout << "znaleziono " << fib(n, modulo) << " " << do_znalezienia<< " " << n << endl; //getch(); wynik=czy_da_sie( do_znalezienia, do_dodania, n, nastepny_przeskok(przeskok), modulo, cel); if(wynik) return wynik; } n+=przeskok; } return 0; } int main() { unsigned long long int c, wynik, cel; string s; cel=1; cin >> s; c=s.length(); while(c--) cel*=10; c=atoll(s.c_str()); wynik=czy_da_sie(0, c, 1, 1, 1, cel); if(wynik) cout << wynik; else cout << "NIE"; return 0; } |
English