mr_dot_convict

Fn = Fn-1 + Fn-2 + Fn-3, mr.convict

Jul 7th, 2019
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.13 KB | None | 0 0
  1. /*author* Priyanshu Shrivastav (from IIT Palakkad) *
  2.  * *_ __ ___  _ ______ ___  _ ____   ___  ___| |_  *
  3.  * | '_ ` _ \| '__/ __/ _ \| '_ \ \ / / |/ __| __| *
  4.  * | | | | | | | | (_| (_) | | | \ V /| | (__| |_  *
  5.  * |_| |_| |_|_|(_)___\___/|_| |_|\_/ |_|\___|\__| *
  6. When I wrote this, only God and I understood what I was doing
  7.  ** * * * * * * * Now, only God knows * * * * * * */
  8. #include <bits/stdc++.h>
  9. using namespace std;
  10. using ll = long long;
  11.  
  12. const int MOD = (int)1e9 + 7;
  13. ll n;
  14. inline int mul(int a, int b)
  15. {
  16.    return int(1ll*a*b % MOD);
  17. }
  18. inline int add (int a, int b)
  19. {
  20.    return (a + b)%MOD;
  21. }
  22.  
  23. struct Mat
  24. {
  25.    int sz;
  26.    static const int mxn = 55;
  27.    int M[mxn][mxn];
  28.  
  29.    Mat(int n_)
  30.    {
  31.       sz = n_;
  32.       reset();
  33.    }
  34.  
  35.    Mat(const Mat& other)
  36.    {
  37.       sz = other.sz;
  38.       for (int i = 0; i < sz; ++i)
  39.          for (int j = 0; j < sz; ++j)
  40.             M[i][j] = other.M[i][j];
  41.    }
  42.  
  43.    void reset()
  44.    {
  45.       for (int i = 0; i < sz; ++i) for (int j = 0; j < sz; ++j)
  46.             M[i][j] = 0;
  47.    }
  48.  
  49.    void make_I()
  50.    {
  51.       for (int i = 0; i < sz; ++i) for (int j = 0; j < sz; ++j)
  52.          M[i][j] = (i == j ? 1 : 0);
  53.    }
  54.  
  55.    Mat operator+(const Mat &other)  // O(n^2)
  56.    {
  57.       Mat sum(sz);
  58.       for (int i = 0; i < sz; ++i)
  59.          for (int j = 0; j < sz; ++j)
  60.             sum.M[i][j] = add(M[i][j], other.M[i][j]);
  61.       return sum;
  62.    }
  63.  
  64.    Mat operator*(const Mat &other) // O(n^3)
  65.    {
  66.       Mat prod(sz);
  67.       for (int i = 0; i < sz; ++i)
  68.          for (int j = 0; j < sz; ++j)
  69.             for (int k = 0; k < sz; ++k)
  70.                prod.M[i][j] =
  71.                   add(prod.M[i][j], mul(M[i][k], other.M[k][j]));
  72.       return prod;
  73.    }
  74.  
  75.    Mat pow(ll k) // O(n^3*logk)
  76.    {
  77.       Mat M_cp(*this), res(sz);
  78.       res.make_I();
  79.  
  80.       assert(k >= 0);
  81.       while (k)
  82.       {
  83.          if (k & 1) res = res * M_cp;
  84.          M_cp = M_cp * M_cp;
  85.          k >>= 1;
  86.       }
  87.       return res;
  88.    }
  89.  
  90.    friend istream& operator >> (istream &is, Mat& o)
  91.    {
  92.       for (int i = 0; i < o.sz; ++i) for (int j = 0; j < o.sz; ++j)
  93.             cin >> o.M[i][j];
  94.       return is;
  95.    }
  96.    friend ostream& operator << (ostream &os, const Mat& o)
  97.    {
  98.       for (int i = 0; i < o.sz; ++i) for (int j = 0; j < o.sz; ++j)
  99.          os << o.M[i][j] << (j == o.sz -1 ? '\n' : ' ');
  100.       return os;
  101.    }
  102.  
  103. };
  104.  
  105. void solve()
  106. {
  107.    if (n == 1) cout << 1 << '\n';
  108.    else if (n == 2) cout << 2 << '\n';
  109.    else {
  110.       Mat base(3);
  111.       base.M[1][0] = base.M[2][1] = base.M[0][0] =  base.M[0][1] =  base.M[0][2] = 1;
  112.  
  113.       base = base.pow(n-2);
  114.       int ans = add(add(mul(base.M[0][0], 2), mul(base.M[0][1],1)), base.M[0][2]);
  115.       cout << ans << '\n';
  116.    }
  117. }
  118.  
  119. signed main()
  120. {
  121.    int tc;
  122.    cin >> tc;
  123.    while (tc--) cin >> n, solve();
  124.    return EXIT_SUCCESS;
  125. }
  126.  
  127.  /*
  128.        * dp(n) = dp(n-1) + dp(n-2) + dp(n-3)
  129.        *
  130.        *         | 1 1 1 |
  131.        * base =  | 1 0 0 |
  132.        *         | 0 1 0 |
  133.        *
  134.        * |dp(n)  |                    |dp(2)|
  135.        * |dp(n-1)| = (base ^ (n-2)) * |dp(1)|
  136.        * |dp(n-2)|                    |dp(0)|
  137.        */
Add Comment
Please, Sign In to add comment