矩阵是干什么的呢?一句话来说就是,知道相邻两个函数的递推关系和第一个数,让你递推到第n个数。显然,如果n很大,那么一个一个递推过去是会超时的。所以矩阵就是用来解决这种快速递推的问题的。

  比方说斐波那契数列就是一个递推的典型。

  先丢题目链接:我是题目!

  那么问题的关键就变成了如何找递推关系的中介矩阵temp了。如果题目告诉了你递推关系,题目就变得很简单了。但是告诉你递推关系大致可分为两类,一类是加法的递推,像斐波那契数列,temp矩阵的每个元素都是常数。另外一种,就是有乘法的递推关系了,这类关系一般需要凑出来,有时候隐晦的话也不是那么容易的。比如说上面题目中的I题,就是需要拼凑的。

  总之先交代模板,先看H题。这题求矩阵sum(A)=A^1+A^2+A^3+...+A^n。方法的话是二分,左边这个式子如果n是偶数的话可以拆成(1+A^(n/2))*(A^1+A^2+...+A(n/2)),然后右边部分又可以递归,不断二分地递归即可。当然,如果n是奇数要再加上A^n;另外上面式子中的1在这里指的是同阶的单位矩阵。代码如下(也可以直接当做矩阵的模板了):

  1 #include <stdio.h>
  2 #include <algorithm>
  3 #include <math.h>
  4 #include <vector>
  5 #include <map>
  6 #include <set>
  7 #include <iostream>
  8 #include <string.h>
  9 #pragma comment(linker, "/STACK:1024000000,1024000000")
 10 using namespace std;
 11 typedef long long ll;
 12 typedef pair<int,int> pii;
 13 const int mod = 10;
 14 
 15 //int mod;
 16 
 17 void add(int &a,int b)
 18 {
 19     a += b;
 20     if(a < 0) a += mod;
 21     //if(a >= mod) a -= mod;
 22     a %= mod;
 23 }
 24 
 25 struct matrix
 26 {
 27     int e[50+5][50+5],n,m;
 28     matrix() {}
 29     matrix(int _n,int _m): n(_n),m(_m) {memset(e,0,sizeof(e));}
 30     matrix operator * (const matrix &temp)const
 31     {
 32         matrix ret = matrix(n,temp.m);
 33         for(int i=1;i<=ret.n;i++)
 34         {
 35             for(int j=1;j<=ret.m;j++)
 36             {
 37                 for(int k=1;k<=m;k++)
 38                 {
 39                     add(ret.e[i][j],1LL*e[i][k]*temp.e[k][j]%mod);
 40                 }
 41             }
 42         }
 43         return ret;
 44     }
 45     matrix operator + (const matrix &temp)const
 46     {
 47         matrix ret = matrix(n,m);
 48         for(int i=1;i<=n;i++)
 49         {
 50             for(int j=1;j<=m;j++)
 51             {
 52                 add(ret.e[i][j],(e[i][j]+temp.e[i][j])%mod);
 53             }
 54         }
 55         return ret;
 56     }
 57     void getE()
 58     {
 59         for(int i=1;i<=n;i++)
 60         {
 61             for(int j=1;j<=m;j++)
 62             {
 63                 e[i][j] = i==j?1:0;
 64             }
 65         }
 66     }
 67 };
 68 
 69 matrix qpow(matrix temp,int x)
 70 {
 71     int sz = temp.n;
 72     matrix base = matrix(sz,sz);
 73     base.getE();
 74     while(x)
 75     {
 76         if(x & 1) base = base * temp;
 77         x >>= 1;
 78         temp = temp * temp;
 79     }
 80     return base;
 81 }
 82 
 83 void print(matrix p)
 84 {
 85     int n = p.n;
 86     int m = p.m;
 87     for(int i=1;i<=n;i++)
 88     {
 89         for(int j=1;j<=m;j++)
 90         {
 91             printf("%d ",p.e[i][j]);
 92         }
 93         cout << endl;
 94     }
 95 }
 96 
 97 matrix solve(matrix a, int k)
 98 {
 99     if(k == 1) return a;
100     int n = a.n;
101     matrix temp = matrix(n,n);
102     temp.getE();
103     if(k & 1)
104     {
105         matrix ex = qpow(a,k);
106         k--;
107         temp = temp + qpow(a,k/2);
108         return temp * solve(a,k/2) + ex;
109     }
110     else
111     {
112         temp = temp + qpow(a,k/2);
113         return temp * solve(a,k/2);
114     }
115 }
116 
117 int main()
118 {
119     int n,k;
120     while(scanf("%d%d",&n,&k)==2 && n)
121     {
122         matrix a = matrix(n,n);
123         for(int i=1;i<=n;i++)
124         {
125             for(int j=1;j<=n;j++) {scanf("%d",&a.e[i][j]);a.e[i][j] %= mod;} 
126             // 这里矩阵的每个元素在输入以后就要mod一下,不然可能会因为输入的元素太大导致在后面爆int(?)
127         }
128         matrix ans = solve(a,k);
129         for(int i=1;i<=n;i++)
130         {
131             for(int j=1;j<=n;j++)
132             {
133                 printf("%d%c",ans.e[i][j],j==n?'\n':' ');
134             }
135         }
136         puts("");
137     }
138 }
矩阵模板

相关文章:

  • 2021-11-04
  • 2022-01-07
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-12-28
  • 2021-12-28
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2021-08-07
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案