矩阵快速幂的初识POJ 3734 Blocks
参考出处:www.cnblogs.com/yan-boy/archive/2012/11/29/2795294.html
www.cnblogs.com/cmmdc/p/6936196.html
blog.csdn.net/clz16251102113/article/details/81152161
整数快速幂的基本结构:
1 int KSM(int x,int n){ 2 int res=x,ans=1; 3 while(n){ 4 if(n&1)ans=ans*res; 5 res=res*res; 6 n>>=1; 7 } 8 return ans; 9 }
整数快速幂的是将一个res的n次方通过将n转化二进制的方式,从低位到高位依次通过不断成倍r增加es,当对应n的二进制位为1时,将此时的res乘积到结果ans中,将求res的n次幂的时间复杂度降为log(n),并且将求幂运算的内部过程显示出来,我们可以对其内部的过程进行操作(例如求模取余)。
而矩阵快速幂这是将res和ans的类型转为矩阵,通过编写矩阵乘法可以利用矩阵的优点解决许多赋值问题。
假设一个n*n的矩阵,它的矩阵快速幂的模板如下:
1 struct node{ 2 int a[n][n]; 3 }res,ans; 4 node MatrixMul(node p,node q){ 5 node temp; 6 for(int i=0;i<n;i++) 7 for(int j=0;j<n;j++){ 8 temp.a[i][j]=0; 9 for(int k=0;k<n;k++) 10 temp.a[i][j]=temp.a[i][j]+p.a[i][k]*q.a[k][j]; 11 } 12 return temp; 13 } 14 node KSM(int n,int N){ 15 for(int i=0;i<n;i++) 16 for(int j=0;j<n;j++) 17 ans.a[i][j]=(i==j); 18 while(N){ 19 if(N&1)ans=MatrixMul(ans,res); 20 res=MatrixMul(res,res); 21 n>>=1; 22 } 23 return ans; 24 }
POJ 3734 Blocks代码:
#include<cstdio> #define ll long long #define MOD 10007 const int N=15; struct node{ int a[N][N]; }s,e; //矩阵快速幂 //矩阵乘法 node mul(node c,node d){ node temp; for(int i=0;i<3;i++){ for(int j=0;j<3;j++){ temp.a[i][j]=0; for(int k=0;k<3;k++){ temp.a[i][j]=(temp.a[i][j]+c.a[i][k]*d.a[k][j])%MOD; } } } return temp; } //快速幂 node f(node s,ll n){ node temp; for(int i=0;i<3;i++){ for(int j=0;j<3;j++){ temp.a[i][j]=(i==j); } } while(n){ if((n&1)==1){ temp=mul(temp,s); } s=mul(s,s); n>>=1; } return temp; } int main(){ ll t,n; scanf("%lld",&t); s.a[0][0]=2; s.a[0][1]=1; s.a[0][2]=0; for(int i=0;i<3;i++)s.a[1][i]=2; s.a[2][0]=0; s.a[2][1]=1; s.a[2][2]=2; while(t--){ scanf("%lld",&n); e=f(s,n); printf("%d\n",e.a[0][0]); } return 0; }
浙公网安备 33010602011771号