//参考にした: //この記事読むまでgmpのライブラリがデフォルトで入ってるって気づいてなかった、けど考えたら入っててもおかしくないか… #include #include #include using namespace std; #if defined(_WIN32) extern "C" { void* __stdcall LoadLibraryA(const char *name); void* __stdcall GetProcAddress(void *handle, const char *name); } struct DynamicLibrary { DynamicLibrary(const char *name) { _handle = LoadLibraryA(name); } void *get(const char *name) const { void *p = GetProcAddress(_handle, name); if(!p) cerr << "can't find: " << name << endl; return p; } void *_handle; } gmp("mpir.dll"); #else extern "C" { void* __libc_dlopen_mode(const char *x, int y); void* __libc_dlsym(void *x, const char *y); } struct DynamicLibrary { DynamicLibrary(const char *name) { _handle = __libc_dlopen_mode(name, 2); } void *get(const char *name) const { void *p = __libc_dlsym(_handle, name); if(!p) cerr << "can't find: " << name << endl; return p; } void *_handle; } gmp("/usr/lib64/libgmp.so.10"); #endif #define DECL_GMP(name) const auto my_##name = (decltype(::name)*)gmp.get("__g" #name) DECL_GMP(mpz_init); DECL_GMP(mpz_clear); DECL_GMP(mpz_set); DECL_GMP(mpz_set_ui); DECL_GMP(mpz_add); DECL_GMP(mpz_add_ui); DECL_GMP(mpz_sub); DECL_GMP(mpz_sub_ui); DECL_GMP(mpz_mul); DECL_GMP(mpz_mul_ui); DECL_GMP(mpz_sizeinbase); DECL_GMP(mpz_get_str); void fib_pair(int n, mpz_t res_a, mpz_t res_b) { if(n <= 2) { my_mpz_set_ui(res_a, (n + 1) / 2); my_mpz_set_ui(res_b, (n + 2) / 2); return; } mpz_t a, b, c, d; my_mpz_init(a); my_mpz_init(b); my_mpz_init(c); my_mpz_init(d); fib_pair(n / 2 - 1, a, b); my_mpz_mul(a, a, a); my_mpz_mul(b, b, b); my_mpz_add(c, b, a); my_mpz_mul_ui(d, b, 4); my_mpz_sub(d, d, a); if(n >> 1 & 1) my_mpz_sub_ui(d, d, 2); else my_mpz_add_ui(d, d, 2); if(n & 1) { my_mpz_set(res_a, d); my_mpz_mul_ui(res_b, d, 2); my_mpz_sub(res_b, res_b, c); } else { my_mpz_sub(res_a, d, c); my_mpz_set(res_b, d); } my_mpz_clear(a); my_mpz_clear(b); my_mpz_clear(c); my_mpz_clear(d); } int main() { int n; while(~scanf("%d", &n)) { if(n == 2) { puts("3\nINF"); } else { mpz_t ans, a, b; my_mpz_init(ans); my_mpz_init(a); my_mpz_init(b); if(n % 2 == 1) { fib_pair(n, a, b); my_mpz_set(ans, a); } else { fib_pair(n / 2 - 1, a, b); my_mpz_mul(ans, a, b); my_mpz_mul_ui(ans, ans, 2); } size_t bufsize = my_mpz_sizeinbase(ans, 10) + 2; char *buf = new char[bufsize]; my_mpz_get_str(buf, 10, ans); printf("%d\n", n); puts(buf); delete[] buf; my_mpz_clear(b); my_mpz_clear(a); my_mpz_clear(ans); } } return 0; }