Advertisement
maiden18

Matrix Inverse with Mod

Nov 13th, 2019
444
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.54 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. #define MOD 1000000007
  3. #define MAX 100
  4.  
  5. using namespace std;
  6. typedef long long ll;
  7.  
  8. ll BigMod(ll a,ll r,ll Mod)
  9. {
  10.     ll ret=1;
  11.     while(r)    {
  12.         if(r&1)    {
  13.             ret=ret*a;
  14.             ret=ret%Mod;
  15.         }
  16.         a=a*a;
  17.         a=a%Mod;
  18.         r=r/2;
  19.     }
  20.     return ret;
  21. }
  22.  
  23.  
  24. ll InverseMod(ll a,ll Mod)
  25. {
  26.     return BigMod(a,Mod-2,Mod);
  27. }
  28.  
  29. ll Mul(ll x,ll y) {
  30.     return (x*y)%MOD;
  31. }
  32.  
  33. ll Div(ll x,ll y) {
  34.     return (x*InverseMod(y, MOD))%MOD;
  35. }
  36.  
  37. //1-based
  38. struct Matrix{
  39.     int row, col;
  40.     ll m[MAX][MAX];
  41.     Matrix() {memset(m,0,sizeof(m));}
  42.     void Set(int r,int c) {row = r; col = c;}
  43.     Matrix(int r,int c) {memset(m,0,sizeof(m)); Set(r,c);}
  44.     void normalize(){
  45.         for(int i=1; i<=row; i++){
  46.             for(int j=1; j<=col; j++){
  47.                 m[i][j] %= MOD;
  48.                 if(m[i][j] < 0) m[i][j] += MOD;
  49.             }
  50.         }
  51.     }
  52. };
  53.  
  54. ll Det(Matrix mat){
  55.     assert(mat.row == mat.col);
  56.     int n = mat.row;
  57.     mat.normalize();
  58.  
  59.     ll ret = 1;
  60.     for(int i = 1; i <= n; i++){
  61.         for(int j = i + 1; j <= n; j++){
  62.             while(mat.m[j][i]){
  63.                 ll t = Div(mat.m[i][i], mat.m[j][i]);
  64.                 for(int k = i; k <= n; ++k){
  65.                     mat.m[i][k] -= Mul(mat.m[j][k] , t);
  66.                     if(mat.m[i][k] < 0) mat.m[i][k] += MOD;
  67.                     swap(mat.m[j][k], mat.m[i][k]);
  68.                 }
  69.                 ret = MOD - ret;
  70.             }
  71.         }
  72.  
  73.         if(mat.m[i][i] == 0) return 0;
  74.         ret = Mul(ret, mat.m[i][i]);
  75.     }
  76.  
  77.     if(ret < 0) ret += MOD;
  78.     return ret;
  79. }
  80.  
  81. ll Tmp[MAX<<1][MAX<<1];
  82. Matrix Inverse(Matrix mat){
  83.     assert(mat.row == mat.col);
  84.     assert(Det(mat) != 0);
  85.  
  86.     int n = mat.row;
  87.     mat.normalize();
  88.     for(int i=1;i<=n;i++){
  89.         for(int j=1;j<=n;j++) Tmp[i][j] = mat.m[i][j];
  90.         for(int j=n+1; j<=2*n; j++) Tmp[i][j] = 0;
  91.         Tmp[i][i+n] = 1;
  92.     }
  93.  
  94.     for(int i=1; i<=n; i++){
  95.         assert(Tmp[i][i] != 0);
  96.  
  97.         for(int j=1; j<=n; j++){
  98.             if(i == j) continue;
  99.             ll c = Div(Tmp[j][i], Tmp[i][i]);
  100.             for(int k=i; k<=2*n; k++){
  101.                 Tmp[j][k] = Tmp[j][k] - Mul(Tmp[i][k], c);
  102.                 if(Tmp[j][k] < 0) Tmp[j][k] += MOD;
  103.             }
  104.         }
  105.     }
  106.  
  107.     Matrix Inv(n,n);
  108.     for(int i=1; i<=n; i++){
  109.         for(int j = 1; j <= n; j++){
  110.             Inv.m[i][j] = Div(Tmp[i][j+n], Tmp[i][i]);
  111.         }
  112.     }
  113.     return Inv;
  114. }
  115.  
  116. int main() {
  117.     return 0;
  118. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement