初等变换求 |A| % Mod & A- % Mod & A* % Mod(模板)

 1 // |A| * A- = A* (伴随矩阵) = 逆矩阵 * 矩阵的值
 2
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<cstdlib>
 6 #include<cmath>
 7 #include<ctime>
 8 #include<iostream>
 9 #include<algorithm>
10 using namespace std;
11
12 const int MAXN = 205;
13 const int Mod = 1000000007;
14 int a[MAXN][MAXN], b[MAXN][MAXN];
15
16 int fast_pow(int a, int k){
17     int res = 1;
18     while(k){
19         if(k & 1) res = 1LL * res * a % Mod;
20         a = 1LL * a * a % Mod;
21         k >>= 1;
22     }
23     return res;
24 }
25
26 void solve(int n){
27     for(int i = 1; i <= n; i++){
28         for(int j = 1; j <= n; j++){
29             b[i][j] = (i==j);//初始 b 为单位矩阵
30         }
31     }
32
33     int det = 1;
34     for(int i = 1; i <= n; i++){
35         int t = i;
36         for(int k = i; k <= n; k++){
37             if(a[k][i]) t = k;
38         }
39
40         if(t != i) det *= -1;
41         for(int j = 1; j <= n; j++){
42             swap(a[i][j], a[t][j]);
43             swap(b[i][j], b[t][j]);
44         }
45
46         det = 1LL * a[i][i] * det % Mod;
47         int inv = fast_pow(a[i][i], Mod-2); // a[i][i] 的逆元
48
49         for(int j = 1; j <= n; j++){
50             a[i][j] = 1LL * inv * a[i][j] % Mod;
51             b[i][j] = 1LL * inv * b[i][j] % Mod;
52         }
53         for(int k = 1; k <= n; k++){
54             if(k == i) continue;
55             int tmp = a[k][i];
56             for(int j = 1; j <= n; j++){
57                 a[k][j] = (a[k][j] - 1LL * a[i][j] * tmp % Mod + Mod) % Mod;
58                 b[k][j] = (b[k][j] - 1LL * b[i][j] * tmp % Mod + Mod) % Mod;
59             }
60         }
61     }
62     //经过增广矩阵初等变换,此时 b 为 a 的逆矩阵
63     det = (det + Mod) % Mod;  //    |a| % Mod
64     for(int i = 1; i <= n; i++){
65         for(int j = 1; j<= n; j++){
66             b[i][j] = 1LL * det * b[i][j] % Mod;  //    将 b 由逆矩阵变成伴随矩阵
67         }
68     }
69 }
70
71 int main(void){
72     int n;
73     while(scanf("%d",&n)!=EOF){
74         for(int i = 1; i <= n; i++)
75             for(int j = 1; j <= n; j++)
76                 scanf("%d", &a[i][j]);
77         solve(n);
78         for(int i = 1; i <= n; i++)
79             printf("%d%c",(i & 1 ? b[i][1] : (Mod - b[i][1]) % Mod), " \n" [i == n]);
80     }
81     return 0;
82 }

时间复杂度为 O(n^3)

时间: 2024-08-28 05:55:02

初等变换求 |A| % Mod & A- % Mod & A* % Mod(模板)的相关文章

n对mod求模整除时转化成mod的数学式

n对mod求模,它的值在0到mod-1之间,如果要求模整除的时候转化成mod可以用下面的式子: n = (n - 1 % mod + mod) % mod +1 这里先减一,模上mod再加一,这样如果是整除mod的话先减一模上之后就变成mod-1,最后+1就变成mod了 这里模mod的方法是先模mod再加mod再模mod,这是常用的做法,目的是为了使得模的结过为正数,而不是负数. 原文地址:https://www.cnblogs.com/fzl194/p/9027068.html

求a^b的约数对mod取模

const int maxn=30000+5; int prime[maxn]; void marktable(int n){ memset(prime,0,sizeof(prime)); for(int i=2;i<=n;i++){ if(!prime[i]) prime[++prime[0]]=i; for(int j=1;j<=prime[0]&&prime[j]<=n/i;j++){ prime[prime[j]*i]=1; if(i%prime[j]==0) b

求C(p,q)%MOD(主要处理n!%MOD的求法)

#define ll long long #define maxn 1000010 #define MOD 1000000007 ll f[maxn],ny[maxn]; ll inv(ll a,ll m){ ll p=1,q=0,b=m,c,d; while(b>0){ c=a/b; d=a; a=b; b=d%b; d=p; p=q; q=d-c*q; } return p<0?p+m:p; } void init(){ f[0]=1; ny[0]=inv(f[0],MOD); for(i

FUZ 1759 Super A^B mod C (指数循环节/模板)

题意:求A^B mod C,其中(1<=A,C<=1000000000,1<=B<=10^1000000). 思路: 在有些题目中我们需要对指数进行降幂处理才能计算.比如计算 其中和 这里由于很大,所以需要进行降幂.那么实际上有如下降幂公式 有了上述公式,很多题目就可以迎刃而解了. 摘自ACdreamer博客 代码: #include <iostream> #include <string.h> #include <stdio.h> using

利用初等变换求逆矩阵和解矩阵方程

求行列式,验证矩阵可逆 原文地址:https://www.cnblogs.com/YC-L/p/12234164.html

manacher求最长回文子串算法模板

#include <iostream> #include <cstring> #include <cstdlib> #include <stdio.h> #include <string> #include <math.h> #include <stdlib.h> using namespace std; int p[maxn]; char s[maxn]; void manacher(char *s){//时间复杂度O(

自己写的求最大值实现,用到了模板函数。

#include <iostream> using namespace std; template <class Type> Type max(Type *c,int d) { Type b=c[0]; int i; for(i=0;i<d;i++) { if(c[i]>b) b=c[i]; } return b; } void main(){ int size,i; cout<<"请输入数组长度"<<endl; cin>

【POJ3352】Road Construction tarjan求边-双连通分量,裸题模板题

转载请注明出处:http://blog.csdn.net/vmurder/article/details/42671851 其实我就是觉得原创的访问量比未授权盗版多有点不爽233... 裸题只给模板. tarjan可以实现. 太水不发题解. 代码: #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define N 1010 #define M 202

O(n)求素数,求欧拉函数,求莫比乌斯函数,求对mod的逆元,各种求

筛素数 void shai() { no[1]=true;no[0]=true; for(int i=2;i<=r;i++) { if(!no[i]) p[++p[0]]=i; int j=1,t=i*p[1]; while(j<=p[0] && t<=r) { no[t]=true; if(i%p[j]==0) //每一个数字都有最小质因子.这里往后的数都会被筛过的,break break; t=i*p[++j]; } } } O(n)筛欧拉函数 void find()