Wednesday, January 16, 2019

[Light OJ] 1131 - Just Two Functions

Author            : Dipu Kumar Mohanto 
                    CSE, Batch - 6
                    BRUR.
Problem Statement : 1131 - Just Two Functions
Source            : UVA Online Judge
Category          : Linear Algebra
Algorithm         : Matrix Exponentiation
Verdict           : Accepted

  1. #include "bits/stdc++.h"  
  2.   
  3. using namespace std;  
  4.   
  5. #define For(i, n)             for (int i = 0; i < n; i++)  
  6. #define FOR(i, n)             for (int i = 1; i <= n; i++)  
  7. #define REP(i, a, b)          for (int i = a; i <= b; i++)  
  8.   
  9. #define ll                    long long int  
  10.   
  11. ll mod;  
  12. ll f[4], g[4];  
  13. ll a[2], b[2];  
  14. ll c[2];  
  15.   
  16. struct Mat  
  17. {  
  18.       int row, col;  
  19.       ll v[7][7];  
  20.       Mat(int row = 0, int col = 0)  
  21.       {  
  22.             this->row = row;  
  23.             this->col = col;  
  24.             For(i, 6) For(j, 6) v[i][j] = 0;  
  25.             v[0][0] = a[0];  
  26.             v[0][1] = b[0];  
  27.             v[0][5] = c[0];  
  28.             v[1][0] = 1;  
  29.             v[2][1] = 1;  
  30.             v[3][2] = c[1];  
  31.             v[3][3] = a[1];  
  32.             v[3][4] = b[1];  
  33.             v[4][3] = 1;  
  34.             v[5][4] = 1;  
  35.       }  
  36.       inline Mat multiply(const Mat &A, const Mat &B)  
  37.       {  
  38.             Mat ret;  
  39.             ret.row = A.row;  
  40.             ret.col = B.col;  
  41.             For(i, ret.row)  
  42.             {  
  43.                   For(j, ret.col)  
  44.                   {  
  45.                         ll sum = 0;  
  46.                         For(k, A.col)  
  47.                         {  
  48.                               sum += (A.v[i][k] % mod * B.v[k][j] % mod) % mod;  
  49.                               sum %= mod;  
  50.                         }  
  51.                         ret.v[i][j] = sum;  
  52.                   }  
  53.             }  
  54.             return ret;  
  55.       }  
  56.       inline Mat modPow(Mat mat, ll p)  
  57.       {  
  58.             if (p == 1) return mat;  
  59.             if (p & 1) return mat.multiply(mat, modPow(mat, p-1));  
  60.             Mat ret = modPow(mat, p >> 1);  
  61.             return ret.multiply(ret, ret);  
  62.       }  
  63.       inline void getRes()  
  64.       {  
  65.             ll fn = 0;  
  66.             fn = (fn + (v[0][0] * f[2]) % mod) % mod;  
  67.             fn = (fn + (v[0][1] * f[1]) % mod) % mod;  
  68.             fn = (fn + (v[0][2] * f[0]) % mod) % mod;  
  69.             fn = (fn + (v[0][3] * g[2]) % mod) % mod;  
  70.             fn = (fn + (v[0][4] * g[1]) % mod) % mod;  
  71.             fn = (fn + (v[0][5] * g[0]) % mod) % mod;  
  72.   
  73.             ll gn = 0;  
  74.             gn = (gn + (v[3][0] * f[2]) % mod) % mod;  
  75.             gn = (gn + (v[3][1] * f[1]) % mod) % mod;  
  76.             gn = (gn + (v[3][2] * f[0]) % mod) % mod;  
  77.             gn = (gn + (v[3][3] * g[2]) % mod) % mod;  
  78.             gn = (gn + (v[3][4] * g[1]) % mod) % mod;  
  79.             gn = (gn + (v[3][5] * g[0]) % mod) % mod;  
  80.   
  81.             printf("%lld %lld\n", fn, gn);  
  82.       }  
  83. };  
  84.   
  85. inline void res(int n)  
  86. {  
  87.       printf("%lld %lld\n", f[n] % mod, g[n] % mod);  
  88. }  
  89.   
  90. int main()  
  91. {  
  92.       int tc;  
  93.       scanf("%d", &tc);  
  94.       FOR(tcase, tc)  
  95.       {  
  96.             scanf("%lld %lld %lld", &a[0], &b[0], &c[0]);  
  97.             scanf("%lld %lld %lld", &a[1], &b[1], &c[1]);  
  98.             scanf("%lld %lld %lld", &f[0], &f[1], &f[2]);  
  99.             scanf("%lld %lld %lld", &g[0], &g[1], &g[2]);  
  100.             scanf("%lld", &mod);  
  101.             printf("Case %d:\n", tcase);  
  102.             int q;  
  103.             scanf("%d", &q);  
  104.             FOR(_q, q)  
  105.             {  
  106.                   ll n;  
  107.                   scanf("%lld", &n);  
  108.                   if (n <= 2)  
  109.                   {  
  110.                         res(n);  
  111.                         continue;  
  112.                   }  
  113.                   Mat mat(6, 6);  
  114.                   mat = mat.modPow(mat, n-2);  
  115.                   mat.getRes();  
  116.             }  
  117.       }  
  118. }  

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.