рдлрд╛рдЗрдмреЛрдиреИрдЪрд┐ рд╕рдВрдЦреНрдпрд╛ рдЧрдгрдирд╛ рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдХреА рддреБрд▓рдирд╛

рд▓реЗрдЦреЛрдВ рдХреА рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдореЗрдВ, рд╣реЗ рдХреЗ рд▓рд┐рдП Nth рдлрд╛рдЗрдмреЛрдиреИрдЪрд┐ рд╕рдВрдЦреНрдпрд╛ (рд▓реЙрдЧ рдПрди) рдФрд░ рдлрд╛рдЗрдмреЛрдиреИрдЪрд┐ рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреА рдЧрдгрдирд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рдФрд░ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдЗрд╕ рддрдереНрдп рдХреА рдУрд░ рдЗрд╢рд╛рд░рд╛ рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА 100 рд╡реАрдВ рдлрд╛рдЗрдмреЛрдиреИрдЪрд┐ рд╕рдВрдЦреНрдпрд╛ 4 рдмрд╛рдЗрдЯреНрд╕ рдореЗрдВ рдлрд┐рдЯ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИ, рдФрд░ "рд▓рдВрдмреА" рдЕрдВрдХрдЧрдгрд┐рдд рдореЗрдВ рдЧреБрдгрди рдХреА рдЧрддрд┐ рддреЗрдЬ рд╣реИред prosyadetред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдРрд╕реЗ рд╕реБрдЭрд╛рд╡ рдереЗ рдХрд┐ рдЖрджрд┐рдо рдЬреЛрдбрд╝ рддреЗрдЬреА рд╕реЗ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред рдореИрдВрдиреЗ 2 рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдХреА рддреБрд▓рдирд╛ рдХрд░рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓рд┐рдпрд╛ - рд╕рд░рд▓ рдЬреЛрдбрд╝ рдФрд░ рдПрдХ рд▓реЙрдЧрд░рд┐рджрдорд┐рдХ рд╕рдВрдЦреНрдпрд╛ рдХреЗ рд╕рд╛рде рдПрдХ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо - рдФрд░ рд╕реА рдореЗрдВ рдПрдХ рдкрд░реАрдХреНрд╖рдг рдХрд╛рд░реНрдпрдХреНрд░рдо рд▓рд┐рдЦрд╛ред "рд▓рдВрдмреЗ" рдЕрдВрдХрдЧрдгрд┐рдд рдХреЗ рд▓рд┐рдП рдореИрдВрдиреЗ рдЬреАрдПрдордкреА рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ред

рдкрд░реАрдХреНрд╖рдг рдХрд╛рд░реНрдпрдХреНрд░рдо рдХрд╛ рдкрд╛рда
#include <stdio.h> #include <stdlib.h> #include <time.h> #include <gmp.h> void fibonachi1(unsigned int n, mpz_t result); void fibonachi2(unsigned int n, mpz_t result); void dump(unsigned int n); int main(int argc, char* argv[]) { unsigned int n, test_count; clock_t t1, t2; mpz_t result; scanf("%u", &test_count); while (test_count--) { scanf("%u", &n); mpz_init(result); t1 = clock(); fibonachi1(n, result); t2 = clock(); printf("%u\t%u\n", n, (unsigned int)(t2 - t1)); mpz_clear(result); } scanf("%u", &test_count); while (test_count--) { scanf("%u", &n); mpz_init(result); t1 = clock(); fibonachi2(n, result); t2 = clock(); printf("%u\t%u\n", n, (unsigned int)(t2 - t1)); mpz_clear(result); } // dump(10000); return 0; } void fibonachi1(unsigned int n, mpz_t result) { mpz_t last, current; if (n < 2) { mpz_init_set_ui(result, n); } else { mpz_init_set_ui(last, 0); mpz_init_set_ui(current, 1); while (--n > 0) { mpz_swap(last, current); mpz_add(current, current, last); } mpz_swap(current, result); mpz_clear(last); mpz_clear(current); } } void fibonachi2(unsigned int n, mpz_t result) { mpz_t fn, fn1, gn, gn1; if (n < 2) { mpz_init_set_ui(result, n); } else { unsigned mask = 1, m = n; while (m > 1) { m >>= 1; mask <<= 1; } mpz_init_set_ui(fn, 1); mpz_init_set_ui(fn1, 1); mpz_init(gn); mpz_init(gn1); while (mask > 3) { mask >>= 1; mpz_swap(fn, gn); mpz_swap(fn1, gn1); if (n & mask) { mpz_mul(fn, gn1, gn1); mpz_set(fn1, fn); mpz_addmul(fn, gn, gn); mpz_mul(gn, gn, gn1); mpz_add(fn1, fn1, gn); mpz_add(fn1, fn1, gn); } else { mpz_mul(fn, gn, gn1); mpz_add(fn, fn, fn); mpz_mul(gn, gn, gn); mpz_sub(fn, fn, gn); mpz_mul(fn1, gn1, gn1); mpz_add(fn1, fn1, gn); } } if (mask > 1) { mask >>= 1; mpz_swap(fn, gn); mpz_swap(fn1, gn1); if (n & mask) { mpz_mul(fn, gn1, gn1); mpz_addmul(fn, gn, gn); } else { mpz_mul(fn, gn, gn1); mpz_add(fn, fn, fn); mpz_submul(fn, gn, gn); } } mpz_swap(result, fn); mpz_clear(fn1); mpz_clear(gn); mpz_clear(gn1); } } void dump(unsigned int n) { FILE* output; mpz_t result; mpz_init(result); fibonachi1(n, result); output = fopen("alg1.output", "w"); if (output) { mpz_out_str(output, 16, result); fclose(output); } mpz_clear(result); mpz_init(result); fibonachi2(n, result); output = fopen("alg2.output", "w"); if (output) { mpz_out_str(output, 16, result); fclose(output); } mpz_clear(result); } 

рдкрд░реАрдХреНрд╖рдг рдЪрд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрджрд┐рдо рд▓рд┐рдкрд┐
 #!/bin/bash ./main <input.txt >test1.txt ./main <input.txt >test2.txt ./main <input.txt >test3.txt 

рдЗрдирдкреБрдЯ рдбреЗрдЯрд╛:
 15 200000 400000 600000 800000 1000000 1200000 1400000 1600000 1800000 2000000 2200000 2400000 2600000 2800000 3000000 13 50000000 100000000 200000000 300000000 400000000 500000000 600000000 700000000 800000000 900000000 1000000000 1100000000 1200000000 


рдкрд░реАрдХреНрд╖рдг рд╡рд╛рддрд╛рд╡рд░рдг: рд╡рд░реНрдЪреБрдЕрд▓рдмреЙрдХреНрд╕, рдПрдерд▓реЙрди II X3 3.4 GHz, 1 GB RAM, Xubuntu 12.04 64bit, GCC 4.6.3 рд╕рдВрдХрд▓рдХ, O2 рдЕрдиреБрдХреВрд▓рди
рджреВрд╕рд░рд╛ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдмрд╣реБрдд рддреЗрдЬрд╝ рдирд┐рдХрд▓рд╛ред рдореИрдВ рдЕрд░рдмрд╡реАрдВ рдлрд╛рдЗрдмреЛрдиреИрдЪрд┐ рд╕рдВрдЦреНрдпрд╛ рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд╣рд▓реЗ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ рдерд╛ред рдПрд▓реНрдЧреЛрд░рд┐рдердо рдирдВрдмрд░ 2 рдХреЛ рдРрд╕рд╛ рдХрд░рдиреЗ рдореЗрдВ 21 рд╕реЗрдХрдВрдб рдХрд╛ рд╕рдордп рд▓рдЧрд╛ред

рдкрд░рд┐рдгрд╛рдо (рдШрдбрд╝реА рджреНрд╡рд╛рд░рд╛ рд▓реМрдЯрд╛рдП рдЧрдП рд╕рдордп рдХреЗ рдЕрдиреБрд╕рд╛рд░)


рджреВрд╕рд░рд╛ рдЧреНрд░рд╛рдл O (N) рдХреЗ рд╕рдорд╛рди рд╣реИред рдкрд╣рд▓реЗ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХрд╛ рдЧреНрд░рд╛рдл O (N ^ 2) рдХреЗ рд╕рдорд╛рди рд╣реИред



UPD рдПрдХ рд╕рдВрдпреБрдХреНрдд рд╢реЗрдбреНрдпреВрд▓ рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛ред рджреВрд╕рд░рд╛ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдЗрддрдиреА рддреЗрдЬреА рд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдЗрд╕рдХрд╛ рдЪрд▓рдиреЗ рдХрд╛ рд╕рдордп рдШрдбрд╝реА () рдлрд╝рдВрдХреНрд╢рди рдХреА рддреНрд░реБрдЯрд┐ рдХреЗ рдмрд░рд╛рдмрд░ рд╣реИ

рд╡рд╣ рдбреЗрдЯрд╛ рдЬрд┐рд╕ рдкрд░ рдЪрд╛рд░реНрдЯ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ:

Source: https://habr.com/ru/post/In148667/


All Articles