Public model for matrix
以下是可以加减乘除(就是乘逆矩阵啦)以及求若干次幂、行列式和逆的矩阵模板。
欢迎大家指正其中可能存在的错误(只验证了求逆的正确性)。
顺便提一下这种复杂度低于定义式求逆的方法,来自于我的高等代数书,思想就是对分块矩阵(A E)进行行变换从而得到(E A^-1),复杂度与消元一样,都是 O(N^3)的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | const int N=405,ha=1e9+7; inline int add( int x, int y){ x+=y; return x>=ha?x-ha:x;} inline void ADD( int &x, int y){ x+=y; if (x>=ha) x-=ha;} inline int ksm( int x, int y){ int an=1; for (;y;y>>=1,x=x*(ll)x%ha) if (y&1) an=an*(ll)x%ha; return an; } inline int Get_inv( int x){ return ksm(x,ha-2);} struct matrix{ int a[N][N],n; inline void clear(){ memset (a,0, sizeof (a));} inline void Base(){ clear(); for ( int i=1;i<=n;i++) a[i][i]=1;} inline void input(){ scanf ( "%d" ,&n); for ( int i=1;i<=n;i++) for ( int j=1;j<=n;j++) scanf ( "%d" ,a[i]+j); } inline void output(){ for ( int i=1;i<=n;i++){ for ( int j=1;j<=n;j++) printf ( "%d " ,a[i][j]); puts ( "" ); } } inline void swap( int x, int y){ for ( int i=1;i<=n;i++) swap(a[x][i],a[y][i]); } inline void add( int from, int tmp, int to){ for ( int i=1;i<=n;i++) ADD(a[to][i],a[from][i]*(ll)tmp%ha); } inline void mul( int x, int ml){ for ( int i=1;i<=n;i++) a[x][i]=a[x][i]*(ll)ml%ha; } inline int Determinant(){ int an=1; matrix b=* this ; for ( int i=1,o,inv;i<=n;i++){ for (o=i;o<=n;o++) if (b.a[o][i]) break ; if (o>n) return 0; if (o>i){ an=ha-an; b.swap(o,i);} inv=Get_inv(b.a[i][i]); for ( int j=i+1,tmp;j<=n;j++) if (b.a[j][i]) tmp=ha-inv*(ll)b.a[j][i]%ha,b.add(i,tmp,j); an=an*(ll)b.a[i][i]%ha; } return an; } inline matrix ni(){ matrix b; b.n=n,b.Base(); if (!Determinant()) b.clear(); else { //先化成对角线元素都是1的上三角矩阵 for ( int i=1,o,inv;i<=n;i++){ for (o=i;o<=n;o++) if (a[o][i]) break ; if (o>i) swap(o,i),b.swap(o,i); inv=Get_inv(a[i][i]),mul(i,inv),b.mul(i,inv); for ( int j=i+1,tmp;j<=n;j++) if (a[j][i]) tmp=ha-a[j][i],add(i,tmp,j),b.add(i,tmp,j); } //然后再把A消成单位矩阵 for ( int i=n-1;i;i--) for ( int j=i+1;j<=n;j++) if (a[i][j]) b.add(j,ha-a[i][j],i),add(j,ha-a[i][j],i); } return b; } matrix operator +( const matrix &u){ for ( int i=1;i<=n;i++) for ( int j=1;j<=n;j++) ADD(a[i][j],u.a[i][j]); return * this ; } matrix operator -( const matrix &u){ for ( int i=1;i<=n;i++) for ( int j=1;j<=n;j++) ADD(a[i][j],ha-u.a[i][j]); return * this ; } matrix operator *( const matrix &u) const { matrix r; r.clear(),r.n=n; for ( int k=1;k<=n;k++) for ( int i=1;i<=n;i++) for ( int j=1;j<=n;j++) ADD(r.a[i][j],a[i][k]*(ll)u.a[k][j]%ha); return r; } matrix operator /(matrix &u) const { return * this *u.ni(); } matrix operator ^( int &u){ matrix b,c=* this ; b.n=n,b.Base(); for (;u;u>>=1,c=c*c) if (u&1) b=b*c; return b; } }JHY; |
我爱学习,学习使我快乐
标签:
矩阵
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· C++代码改造为UTF-8编码问题的总结
· DeepSeek 解答了困扰我五年的技术问题
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· Deepseek官网太卡,教你白嫖阿里云的Deepseek-R1满血版
· 2分钟学会 DeepSeek API,竟然比官方更好用!
· .NET 使用 DeepSeek R1 开发智能 AI 客户端
· DeepSeek本地性能调优
· 一文掌握DeepSeek本地部署+Page Assist浏览器插件+C#接口调用+局域网访问!全攻略