【未优化的矩阵乘法】
Mat mtMul(Mat A,Mat B)
{
memset(temp2.a,0,sizeof(temp2.a));
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
{
for(int k=0;k<n;k++)
{
temp2.a[i][j]+=A.a[i][k]*B.a[k][j];
temp2.a[i][j]%=m;
}
}
return temp2;
}
【矩阵快速幂的两个非递归写法】
Mat mtPow(Mat A,int time)
{
memset(t.a,0,sizeof(t.a));
for(int i=0;i<n;i++) t.a[i][i]=1;
while(time>0){
if(time&1)
t=mtMul(t,A);
time>>=1;
A=mtMul(A,A);
}
return t;
}
Mat mtPow2(Mat A,int k) // 求矩阵 A ^ k
{
stack<int > st;
while(k)
{
st.push(k&1);
k>>=1;
}
memset(t.a,0,sizeof(t.a));
for(int i=0;i<n;i++) t.a[i][i]=1;
while(!st.empty())
{
t=mtMul(t,t);
if(st.top()==1)
t=mtMul(t,A);
st.pop();
}
return t;
}
【性质:等比矩阵】
【POJ3734】
1 用数学方法,与本专题无关,不表
2 根据 dp 方程 求出 矩阵
代码如下
#include<iostream>
#include<string.h>
#include<cstdio>
#include<stack>
using namespace std;
struct Mat
{
int a[65][65];
};
int N,M;
Mat mtMul(Mat A,Mat B)
{
Mat temp;
memset(temp.a,0,sizeof(temp.a));
for(int i=0;i<N;i++)
for(int j=0;j<N;j++)
{
for(int k=0;k<N;k++)
{
temp.a[i][j]+=A.a[i][k]*B.a[k][j];
temp.a[i][j]%=M;
}
}
return temp;
}
Mat mtPow(Mat A,int time)
{
Mat temp;
memset(temp.a,0,sizeof(temp.a));
for(int i=0;i<N;i++) temp.a[i][i]=1;
while(time>0){
if(time&1)
temp=mtMul(temp,A);
time>>=1;
A=mtMul(A,A);
}
return temp;
}
Mat mtPow2(Mat A,int k) // 求矩阵 A ^ k
{
Mat temp;
stack<int> st;
while(k)
{
st.push(k&1);
k>>=1;
}
memset(temp.a,0,sizeof(temp.a));
for(int i=0;i<N;i++) temp.a[i][i]=1;
while(!st.empty())
{
temp=mtMul(temp,temp);
if(st.top()==1)
temp=mtMul(temp,A);
st.pop();
}
return temp;
}
int base[4][4]={2,1,1,0,1,2,0,1,1,0,2,1,0,1,1,2};
int main()
{
int t;
int k;
cin>>t;
Mat temp;
while(t--)
{
cin>>k;
N=4;
M=10007;
memset(temp.a,0,sizeof(temp.a));
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
temp.a[i][j]=base[i][j];
temp=mtPow2(temp,k);
cout<<temp.a[0][0]<<endl;
}
return 0;
}
【待续……】