整理的算法模板合集: ACM模板
luogu P3390 【模板】矩阵快速幂
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iostream>
using namespace std;
typedef long long ll;
const int N = 107, mod = 1e9 + 7;
int n, m;
int a[N][N];
int ans[N][N];
ll k;
void mul(int c[][N], int a[][N], int b[][N])
{
int tmp[N][N] = {0};
for(int i = 1; i <= n; ++ i){
for(int j = 1; j <= n; ++ j){
for(int k = 1; k <= n; ++ k){
tmp[i][j] = (tmp[i][j] + (ll)a[i][k] * b[k][j]) % mod;
}
}
}
memcpy(c, tmp, sizeof tmp);
}
int main(){
scanf("%d%lld", &n, &k);
for(int i = 1; i <= n; ++ i)
for(int j = 1; j <= n; ++ j)
scanf("%d", &a[i][j]);
for(int i = 1; i <= n; ++ i)
ans[i][i] = 1;
while(k){
if(k & 1) mul(ans, ans, a);
mul(a, a, a);
k >>= 1;
}
for(int i = 1; i <= n;puts(""), ++ i)
for(int j = 1; j <= n; ++ j)
printf("%d ", ans[i][j]);
return 0;
}
AcWing 1303. 斐波那契前 n 项和
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iostream>
using namespace std;
typedef long long ll;
const int N = 3;
int n, m;
int a[N][N];
int f[N];
void mul(int c[], int a[], int b[][N])
{
int tmp[N] = {0};
for(int j = 0; j < N; ++ j){//2的行
for(int k = 0; k < N; ++ k){//1的列2的行,1的列=2的行
//只有一行,求这一行的每一列
tmp[j] = (tmp[j] + (ll)a[k] * b[k][j]) % m;
}
}
memcpy(c, tmp, sizeof tmp);
}
void mul(int c[][N], int a[][N], int b[][N])
{
int tmp[N][N] = {0};
for(int i = 0; i < N; ++ i){
for(int j = 0; j < N; ++ j){
for(int k = 0; k < N; ++ k){
tmp[i][j] = (tmp[i][j] + (ll)a[i][k] * b[k][j]) % m;
}
}
}
memcpy(c, tmp, sizeof tmp);
}
int main()
{
scanf("%d%d", &n, &m);
int f1[N] = {1, 1, 1};
int a[N][N] = {
0, 1, 0,
1, 1, 1,
0, 0, 1
};
n -- ;//这里是从第一项开始的,所以要--;
while(n){
if(n & 1) mul(f1, f1, a);
mul(a, a, a);
n >>= 1;
}
printf("%d\n", f1[2]);
return 0;
}
AcWing 1304. 佳佳的斐波那契
计算公式为:
T
n
=
n
∗
S
n
−
P
n
T_n = n * S_n - P_n
Tn=n∗Sn−Pn
//#pragma GCC optimize(2)
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iostream>
#include <cmath>
using namespace std;
typedef long long ll;
const int N = 4;
int n, m;
int f[N][N];
void mul(int c[][N], int a[][N], int b[][N])
{
static int tmp[N][N];
memset(tmp, 0, sizeof tmp);
for(int i = 0; i < N; ++ i){
for(int j = 0; j < N; ++ j){
for(int k = 0; k < N; ++ k){
tmp[i][j] = (tmp[i][j] + (ll)a[i][k] * b[k][j]) % m;
}
}
}
memcpy(c, tmp, sizeof tmp);
}
int main()
{
scanf("%d%d", &n, &m);
// {fn, fn+1, sn, pn}
// pn = n * sn - tn
int f1[N][N] = {1, 1, 1, 0};
int a[N][N] = {
{0, 1, 0, 0},
{1, 1, 1, 0},
{0, 0, 1, 1},
{0, 0, 0, 1},
};
int k = n - 1;
while(k){
if(k & 1)mul(f1, f1, a);
mul(a, a, a);
k >>= 1;
}
cout << (((ll)n * f1[0][2] - f1[0][3] % m + m) % m) << endl;
return 0;
}