void Fibonacci(__int64 n, BIGNUM &rez) { BIGNUM f1, f2; if (n < HASH) memcpy(rez, Table[n], sizeof(Table[n])); else { memset(rez, 0, sizeof(rez)); if (n & 1) // f[2n-1] = f^2[n] + f^2[n-1] { Fibonacci((n + 1) / 2, f1); Fibonacci(n / 2, f2); BigMul(rez, f1, f1); memset(f1, 0, sizeof(f1)); BigMul(f1, f2, f2); BigAdd(rez, f1); } else // f[2n] = f[n]*(f[n-1] + f[n+1]) { Fibonacci(n / 2 - 1, f1); Fibonacci(n / 2 + 1, f2); BigAdd(rez, f1); BigAdd(rez, f2); Fibonacci(n / 2, f1); BigMul(rez, rez, f1); } } }
int main (int argc, char *argv[]) { int n, x, a1, b1, t, mn; struct BigNum p[3], q[3], mx, my; BigInit(&mx, 0); BigInit(&my, 0); for (n = 2; n < MAX_N; n++) { a1 = 1; x = b1 = sqrt(n); if (x*x == n) continue; BigInit(&p[0], 1); BigInit(&q[0], 0); BigInit(&p[1], x); BigInit(&q[1], 1); if (check_xy(n, &p[1], &q[1])) { printf("N = %d, x = %I64u, y = %I64u\n", n, p[1], q[1]); fflush(stdout); continue; } do { x = get_next_coeff(n, &a1, &b1); BigMultiplyConst(&p[2], &p[1], x); BigAdd(&p[2], &p[2], &p[0]); BigMultiplyConst(&q[2], &q[1], x); BigAdd(&q[2], &q[2], &q[0]); if (check_xy(n, &p[2], &q[2])) { break; } BigAssign(&p[0], &p[1]); BigAssign(&p[1], &p[2]); BigAssign(&q[0], &q[1]); BigAssign(&q[1], &q[2]); } while (1); if (BigCompare(&mx, &p[2]) < 0) { BigAssign(&mx, &p[2]); BigAssign(&my, &q[2]); mn = n; } } printf("\n===== Maximum at N = %d\n", mn); printf("X: "); BigPrint(&mx, mx.n); printf("Y: "); BigPrint(&my, my.n); return 0; }
void BuildTable(int n) { int i; Table[0][0] = Table[1][0] = 1; Table[0][1] = 0; Table[1][1] = 1; for (i = 2; i <= n; i++) { BigAdd(Table[i], Table[i - 1]); BigAdd(Table[i], Table[i - 2]); } }
int main() { scanf("%d", &N); //clock_t start = clock(); BuildTable(HASH - 1); Fibonacci(N - 1, rez1); Fibonacci(N + 1, rez2); BigAdd(rez1, rez2); printf("%d", rez1[rez1[0]]); for (int i = rez1[0] - 1; i > 0; i--) printf(FMT, rez1[i]); printf("\n"); //clock_t end = clock(); //printf("Time = %.4lf\n", (double)(end - start)/CLK_TCK); return 0; }