矩阵快速幂
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <set>
#include <cmath>
using namespace std;
const int N = 150;
const int mod = 1e9 + 7;
typedef long long lld;
inline int read() {
	register int w = 0, f = 1;
	register char c = getchar();
	while (c > '9' || c < '0') {
		if (c == '-')  f = -1;
		c = getchar();
	}
	while (c >= '0' && c <= '9') {
		w = w * 10 + c - '0';
		c = getchar();
	}
	return w * f;
}
int n;
lld k;
struct Mat {
	int dat[N][N];
	Mat () {
		memset(dat, 0, sizeof (dat));
	}
	inline void init() {
		for (register int i = 1; i <= n; ++i)
			dat[i][i] = 1;
	}
	inline void readin() {
		for (register int i = 1; i <= n; ++i)
			for (register int j = 1; j <= n; ++j)
				dat[i][j] = read();
	}		
	inline void print() {
		for (register int i = 1; i <= n; ++i)
			for (register int j = 1; j <= n; ++j)
				printf("%d%c", dat[i][j], j == n ? '\n' : ' ');
	}
};
Mat operator * (register Mat a, register Mat b) {
	register Mat c;
	for (register int i = 1; i <= n; ++i)
		for (register int j = 1; j <= n; ++j)	
			for (register int k = 1; k <= n; ++k)
				c.dat[i][j] = (c.dat[i][j] + 1ll * a.dat[i][k] * b.dat[k][j] % mod) % mod;
	return c;
}
Mat qpow(register Mat a, register lld b) {
	register Mat base;
	base.init();
	while (b) {
		if (b & 1)  base = base * a;
		a = a * a;
		b >>= 1;
	}
	return base;
}
int main() {
	n = read();
	scanf("%lld", &k);
	register Mat a;
	a.readin();
	a = qpow(a, k);
	a.print();
	return 0;
}
矩阵加速
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 5;
const int mod = 1e9 + 7;
typedef long long lld;
inline int read() {
	register int w = 0, f = 1;
	register char c = getchar();
	while (c > '9' || c < '0') {
		if (c == '-')  f = -1;
		c = getchar();
	}
	while (c >= '0' && c <= '9') {
		w = w * 10 + c - '0';
		c = getchar();
	}
	return w * f;
}
struct Mat {
	int n, m;
	int dat[N][N];
	Mat () {
		memset(dat, 0, sizeof (dat));
	}
	inline void init(register int new_n, register int new_m) {
		n = new_n, m = new_m;
		for (register int i = 1; i <= n; ++i)
			dat[i][i] = 1;
	}
	inline void readin() {
		for (register int i = 1; i <= n; ++i)
			for (register int j = 1; j <= m; ++j)
				dat[i][j] = read();
	}		
	inline void print() {
		for (register int i = 1; i <= n; ++i)
			for (register int j = 1; j <= m; ++j)
				printf("%d%c", dat[i][j], j == m ? '\n' : ' ');
	}
};
Mat operator * (register Mat a, register Mat b) {
	register Mat c;
	c.n = a.n;
	c.m = a.m;
	for (register int i = 1; i <= a.n; ++i)
		for (register int j = 1; j <= b.m; ++j)	
			for (register int k = 1; k <= b.n; ++k)
				c.dat[i][j] = (c.dat[i][j] + 1ll * a.dat[i][k] * b.dat[k][j] % mod) % mod;
	return c;
}
inline Mat qpow(register Mat a, register int b) {
	register Mat base;
	base.init(a.n, a.m);
	while (b) {
		if (b & 1)  base = base * a;
		a = a * a;
		b >>= 1;
	}
	return base;
}
int n;
int main() {
	register int T = read();
	while (T--) {
		register Mat a;
		a.n = 1, a.m = 3;
		a.dat[1][1] = a.dat[1][2] = a.dat[1][3] = 1;
		register Mat base;
		base.n = base.m = 3;
		base.dat[1][1] = base.dat[1][2] = base.dat[2][3] = base.dat[3][1] = 1;
		n = read();
		n -= 3;
		if (n <= 0) {
			printf("1\n");
			continue;
		}
		base = qpow(base, n);
		a = a * base;
		printf("%d\n", a.dat[1][1]);
	}
	return 0;
}
高斯消元
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int N = 150;
const double eps = 1e-7;
typedef long long lld;
inline int read() {
	register int w = 0, f = 1;
	register char c = getchar();
	while (c > '9' || c < '0') {
		if (c == '-')  f = -1;
		c = getchar();
	}
	while (c >= '0' && c <= '9') {
		w = w * 10 + c - '0';
		c = getchar();
	}
	return w * f;
}
int n;
double a[N][N], ans[N];
int main() {
	register int T = 1;
	while (T--) {
		n = read();
		for (register int i = 1; i <= n; ++i)
			for (register int j = 1; j <= n + 1; ++j)
				scanf("%lf", &a[i][j]);
		for (register int i = 1; i <= n; ++i) {
			int r = i;
			for (register int j = r + 1; j <= n; ++j)
				if (fabs(a[r][i]) < fabs(a[j][i]))
					r = j;
			if (fabs(a[r][i]) < eps) {
				printf("No Solution\n");
				return 0;
			}
			if (r != i)  swap(a[r], a[i]);
			register double div = a[i][i];
			for (register int j = i; j <= n + 1; ++j)  a[i][j] /= div;
			for (register int j = i + 1; j <= n; ++j) {
				div = a[j][i];
				for (register int k = i; k <= n + 1; ++k)
					a[j][k] -= div * a[i][k];
			}
		}
		ans[n] = a[n][n + 1];
		for (register int i = n - 1; i >= 1; --i) {
			ans[i] = a[i][n + 1];
			for (register int j = i + 1; j <= n; ++j)
				ans[i] -= ans[j] * a[i][j];
		}
		for (register int i = 1; i <= n; ++i)
			printf("%.2lf\n", ans[i]);
	}
	return 0;
}
矩阵求逆
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int N = 450;
const int mod = 1e9 + 7;
inline int read() {
	register int w = 0, f = 1;
	register char c = getchar();
	while (c > '9' || c < '0') {
		if (c == '-')  f = -1;
		c = getchar();
	}
	while (c >= '0' && c <= '9') {
		w = w * 10 + c - '0';
		c = getchar();
	}
	return w * f;
}
int n;
int a[N][N << 1];
inline int qpow(register int a, register int b) {
	register int base = 1;
	while (b) {
		if (b & 1)  base = 1ll * base * a % mod;
		a = 1ll * a * a % mod;
		b >>= 1;
	}
	return base;
}
int main() {
	n = read();
	for (register int i = 1; i <= n; ++i) {
		for (register int j = 1; j <= n; ++j)	
			a[i][j] = read();
		a[i][i + n] = 1;
	}
	for (register int i = 1; i <= n; ++i) {
		register int r = i;
		for (register int j = i + 1; j <= n; ++j)
			if (a[r][i] < a[j][i])  r = j;
		if (r != i)  swap(a[r], a[i]);
		if (!a[i][i]) {
			printf("No Solution\n");
			return 0;
		}
		int div = qpow(a[i][i], mod - 2);
		for (register int k = 1; k <= n; ++k) {
			if (k == i)  continue;
			int p = 1ll * a[k][i] * div % mod;
			for (register int j = 1; j <= 2 * n; ++j)
				a[k][j] = (a[k][j] - 1ll * p * a[i][j] % mod + mod) % mod;
		}
		for (register int j = 1; j <= n * 2; ++j)
			a[i][j] = 1ll * a[i][j] * div % mod;
	}
	for (register int i = 1; i <= n; ++i)
		for (register int j = n + 1; j <= 2 * n; ++j)
			printf("%d%c", a[i][j], j == 2 * n ? '\n' : ' ');
	return 0;
}