Advertisement
Argent007

Про Фибоначчи 3

Feb 22nd, 2023 (edited)
40
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.36 KB | None | 0 0
  1. // ConsoleApplication1.cpp : Этот файл содержит функцию "main". Здесь начинается и заканчивается выполнение программы.
  2. //
  3.  
  4. #include <iostream>
  5. #include <vector>
  6. #include <string>
  7.  
  8. using base = unsigned long long;
  9. const base b12 = 1'000'000'000'000;
  10. const base b8 = 1'000'000'00;
  11.  
  12. class ell
  13. {
  14.    base hi = 0, lo = 0;
  15. public:
  16.    ell() {}
  17.    ell(base n) { lo = n % b12; hi = n / b12; }
  18.    ell operator+(const ell& arg2)const
  19.    {
  20.        ell res;
  21.        res.lo = lo + arg2.lo;
  22.        res.hi = hi + arg2.hi + res.lo / b12;
  23.        res.lo %= b12;
  24.        return res;
  25.    };
  26.    std::string tostring() const {
  27.        std::string res = std::to_string(lo);
  28.        if (hi > 0)
  29.        {
  30.            res = std::to_string(hi) + std::string(12 - res.length(), '0') + res;
  31.        }
  32.        return res;
  33.    }
  34.    friend std::ostream& operator<<(std::ostream& os, const ell& N)
  35.    {
  36.        return os << N.tostring();
  37.    }
  38. };
  39.  
  40. class ell24
  41. {
  42.    base hi = 0, lo = 0, mi = 0;
  43. public:
  44.    ell24() {}
  45.    ell24(base n) { lo = n % b8; n /= b8;  mi = n % b8; hi = n / b8; }
  46.    ell24 operator+(const ell24& arg2)const
  47.    {
  48.        ell24 res;
  49.        res.lo = lo + arg2.lo;
  50.        res.mi = mi + arg2.mi + res.lo / b8;
  51.        res.lo %= b8;
  52.        res.hi = hi + arg2.hi + res.mi / b8;
  53.        res.mi %= b8;
  54.        return res;
  55.    };
  56.    ell24 operator*(const ell24& arg2)const
  57.    {
  58.        ell24 res;
  59.        res.lo = lo * arg2.lo;
  60.        res.mi = lo * arg2.mi + mi * arg2.lo + res.lo / b8;
  61.        res.lo %= b8;
  62.        res.hi = lo * arg2.hi + mi * arg2.mi + hi * arg2.lo + res.mi / b8;
  63.        res.mi %= b8;
  64.        return res;
  65.    }
  66.    std::string tostring() const {
  67.        std::string lo_str = std::to_string(lo); lo_str = std::string(8 - lo_str.length(), '0') + lo_str;
  68.        std::string mi_str = std::to_string(mi); mi_str = std::string(8 - mi_str.length(), '0') + mi_str;
  69.        std::string res = std::to_string(hi) + mi_str + lo_str;
  70.        return std::string(res.begin() + res.find_first_not_of('0'), res.end());
  71.    }
  72.    friend std::ostream& operator<<(std::ostream& os, const ell24& N)
  73.    {
  74.        return os << N.tostring();
  75.    }
  76. };
  77.  
  78.  
  79. std::vector<ell> F(101);
  80.  
  81. base fib(int n)
  82. {
  83.    if (n <= 1)return n;
  84.    return fib(n - 1) + fib(n - 2);
  85. }
  86.  
  87. void fib_iter()
  88. {
  89.    F[0] = 0;
  90.    F[1] = 1;
  91.    for (size_t i = 2; i < 101; i++)
  92.    {
  93.        F[i] = F[i - 1] + F[i - 2];
  94.    }
  95. }
  96.  
  97. //return Fib[n], Fib[n-1], n>0
  98. std::pair<ell24, ell24> Fib_pair(int n)
  99. {
  100.    if (n == 1)
  101.        return { 1,0 };
  102.    if (n % 2 == 1)
  103.    {
  104.        auto prev = Fib_pair(n - 1);
  105.        return { prev.first + prev.second, prev.first };
  106.    }
  107.    auto prev = Fib_pair(n / 2);
  108.    auto fibsqr = prev.first * prev.first;
  109.    auto fibprod = prev.first * prev.second;
  110.    return { fibsqr + fibprod + fibprod, fibsqr + prev.second * prev.second };
  111. }
  112.  
  113. class matrix2x2
  114. {
  115. public:
  116.    ell24 a11, a12, a21, a22;
  117.    matrix2x2 operator*(const matrix2x2& m)const
  118.    {
  119.        matrix2x2 r;
  120.        r.a11 = a11 * m.a11 + a12 * m.a21;
  121.        r.a12 = a11 * m.a12 + a12 * m.a22;
  122.        r.a21 = a21 * m.a11 + a22 * m.a21;
  123.        r.a22 = a21 * m.a12 + a22 * m.a22;
  124.        return r;
  125.    }
  126.    matrix2x2 operator^(int n)const
  127.    {
  128.        matrix2x2 r = { 1,0,0,1 }, p = *this;
  129.        while (n > 0)
  130.        {
  131.            if (n & 1)
  132.                r = r * p;
  133.            n /= 2;
  134.            if (n)
  135.                p = p * p;
  136.        }
  137.        return r;
  138.    }
  139. };
  140.  
  141. int main()
  142. {
  143.    ell24 x(1234567890123), y(98765432101);
  144.    std::cout << x * y << std::endl;
  145.  
  146.    fib_iter();
  147.    for (size_t i = 10; i <= 100; i += 1)
  148.    {
  149.        std::cout << i << ":\t " << F[i] << std::endl;
  150.    }
  151.    auto fibpair100 = Fib_pair(100);
  152.    std::cout << 100 << ":\t " << fibpair100.first << std::endl;
  153.  
  154.    matrix2x2 F{ 1,1,1,0 };
  155.    F = F ^ 99;
  156.    std::cout << F.a11 << std::endl;
  157.  
  158.    std::cout << "Hello World!\n";
  159. }
  160.  
  161. // Запуск программы: CTRL+F5 или меню "Отладка" > "Запуск без отладки"
  162. // Отладка программы: F5 или меню "Отладка" > "Запустить отладку"
  163.  
  164. // Советы по началу работы
  165. //   1. В окне обозревателя решений можно добавлять файлы и управлять ими.
  166. //   2. В окне Team Explorer можно подключиться к системе управления версиями.
  167. //   3. В окне "Выходные данные" можно просматривать выходные данные сборки и другие сообщения.
  168. //   4. В окне "Список ошибок" можно просматривать ошибки.
  169. //   5. Последовательно выберите пункты меню "Проект" > "Добавить новый элемент", чтобы создать файлы кода, или "Проект" > "Добавить существующий элемент", чтобы добавить в проект существующие файлы кода.
  170. //   6. Чтобы снова открыть этот проект позже, выберите пункты меню "Файл" > "Открыть" > "Проект" и выберите SLN-файл.
  171.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement