P3390 【模板】矩阵快速幂
题目背景
矩阵快速幂
题目描述
给定 n×n 的矩阵 A,求 Ak。
输入格式
第一行两个整数 n,k 接下来 n 行,每行 n 个整数,第 i 行的第 j 的数表示 Ai,j。
输出格式
输出 A^k
共 n 行,每行 n 个数,第 i 行第 j 个数表示 (Ak)i,j,每个元素对 10^9+7 取模。
输入输出样例
输入 #1
2 1 1 1 1 1
输出 #1
1 1 1 1
嗯,好吧,步入正题,这是一道洛谷的模板题,本以为能爆踩他的我,结果可想而知。
后来,我总结了一下错误原因,结果发现,我原来主函数里少写一行代码(就无语),然后我就又又又瞎想了一些奇奇怪怪的东西:
快速幂其实就是用的递归公式:

所以,我们用这个推出的代码就应该长这样:
while版:
1 while(x>0) { 2 if(x%2!=0) ans=ans*a; 3 a=a*a; 4 x=x>>1; 5 }
递归版:
1 int K(int a,int n){ 2 if(n==0) 3 return 1; 4 if(n==1) 5 return a; 6 int c=K(a,n/2); 7 if(n%2==0) 8 return c*c; 9 else 10 return c*c*a; 11 }
这说明什么???我们可以用这几段代码稍加修改,把它变成这道题的代码
BUT:!!!它超时了(TLE)
while也不行
呵呵,所以经过我的精心修改,正确的代码他终于来了!!
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<string> 5 #include<cstring> 6 #define LL long long//我真懒,呵呵 7 #define MOD 1000000007 8 using namespace std; 9 LL a[109][109],ans[109][109],cil[109][109],K;//个人习惯 10 int n; 11 void Fk() { 12 while(K) { 13 if(K%2) { 14 for(int i=1; i<=n; i++) 15 for(int j=1; j<=n; j++) 16 cil[i][j]=ans[i][j],ans[i][j]=0; 17 for(int i=1; i<=n; i++) 18 for(int j=1; j<=n; j++) 19 for(int k=1; k<=n; k++) 20 ans[i][j]=(ans[i][j]+cil[i][k]*a[k][j]%MOD)%MOD; 21 } 22 for(int i=1; i<=n; i++) 23 for(int j=1; j<=n; j++) 24 cil[i][j]=a[i][j],a[i][j]=0; 25 for(int i=1; i<=n; i++) 26 for(int j=1; j<=n; j++) 27 for(int k=1; k<=n; k++) 28 a[i][j]=(a[i][j]+cil[i][k]*cil[k][j]%MOD)%MOD; 29 30 K/=2; 31 } 32 } 33 int main() { 34 scanf("%d%lld",&n,&K); 35 for(int i=1; i<=n; i++) 36 for(int j=1; j<=n; j++) 37 scanf("%lld",&a[i][j]); 38 39 for(int i=1; i<=n; i++) 40 for(int j=1; j<=n; j++) 41 ans[i][j]=a[i][j]; 42 43 44 K--; 45 Fk(); 46 47 for(int i=1; i<=n; i++) { 48 for(int j=1; j<=n; j++) printf("%lld ",ans[i][j]); 49 puts(""); 50 } 51 return 0; 52 }
我滴CSDN博客

本文来自博客园,作者:Larryhui,转载请注明原文链接:https://www.cnblogs.com/Larryhui/p/16532415.html
浙公网安备 33010602011771号