矩阵快速幂
Posted leesongt
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了矩阵快速幂相关的知识,希望对你有一定的参考价值。
1 /* 2 题意:求a(n)=a(n-1)+a(n-2)+a(n-3)+......a(n-k)+... k<20 n<10^18 3 题解:矩阵快速幂,把递推公式写成矩阵的形式,就可以利用快速幂计算 4 时间:2018.07.31 5 */ 6 7 #include <bits/stdc++.h> 8 using namespace std; 9 10 typedef long long LL; 11 const int MAXN = 100005; 12 const LL MOD7 = 1e9+7; 13 const LL MOD9 = 1e9+9; 14 15 16 int n,K; 17 LL m; 18 19 struct Matrix 20 { 21 LL a[25][25]; 22 int n; 23 Matrix() 24 { 25 memset(a,0LL,sizeof(a)); 26 n= 20; 27 } 28 Matrix(int n):n(n) 29 { 30 memset(a,0LL,sizeof(a)); 31 } 32 Matrix(const Matrix& T) 33 { 34 this->n = T.n; 35 for (int i=0;i<n;++i) 36 { 37 for (int j=0;j<n;++j) 38 { 39 a[i][j]=T.a[i][j]; 40 } 41 } 42 } 43 44 Matrix operator*(const Matrix& T) 45 { 46 Matrix c(n); 47 for (int i=0;i<n;++i) 48 { 49 for (int j=0;j<n;++j) 50 { 51 for (int k=0;k<n;++k) 52 { 53 c.a[i][j]=(c.a[i][j] + a[i][k]*T.a[k][j] % MOD9) % MOD9; 54 } 55 } 56 } 57 return c; 58 } 59 60 Matrix operator+(const Matrix &T) 61 { 62 Matrix c(n); 63 for (int i=0;i<n;++i) 64 { 65 for (int j=0;j<n;++j) 66 { 67 c.a[i][j] = (c.a[i][j]+a[i][j]+T.a[i][j])%MOD9; 68 } 69 } 70 return c; 71 } 72 73 Matrix operator=(const Matrix &T) 74 { 75 this->n=T.n; 76 for (int i=0;i<n;++i) 77 { 78 for (int j=0;j<n;++j) 79 { 80 a[i][j]=T.a[i][j]; 81 } 82 } 83 } 84 85 void ones() 86 { 87 for (int i=0;i<n;++i) a[i][i]=1; 88 } 89 90 void Print() 91 { 92 for (int i=0;i<n;++i) 93 { 94 for (int j=0;j<n;++j) 95 { 96 printf("%lld ",a[i][j]); 97 } 98 printf(" "); 99 } 100 } 101 }; 102 103 Matrix Pow(Matrix a, LL b) 104 { 105 Matrix res(a.n); 106 res.ones(); 107 Matrix ans(a); 108 while (b) 109 { 110 if (b&1) res=res*ans; 111 ans=ans*ans; 112 b>>=1; 113 } 114 return res; 115 } 116 117 int b[25]; 118 119 int main() 120 { 121 #ifndef ONLINE_JUDGE 122 freopen("test.txt","r",stdin); 123 #endif // ONLINE_JUDGE 124 while (scanf("%d%lld%d",&n,&m,&K)!=-1) 125 { 126 for (int i=1;i<=n;++i) scanf("%d",&b[n-i+1]); 127 Matrix a(n); 128 for (int i=0;i<n-1;++i) a.a[i][i+1]=1; 129 int ck; 130 for (int i=1;i<=K;++i) 131 { 132 scanf("%d",&ck); 133 a.a[ck-1][0]+=1; 134 } 135 // a.Print(); 136 if (m<=n) { 137 printf("%d ",b[n-m+1]); 138 continue; 139 } 140 a=Pow(a,m-n); 141 // a.Print(); 142 LL ans=0; 143 for (int i=0;i<n;++i) 144 ans = (ans + b[i+1]*a.a[i][0]) % MOD9; 145 printf("%lld ",ans); 146 } 147 return 0; 148 }
以上是关于矩阵快速幂的主要内容,如果未能解决你的问题,请参考以下文章