【纽约】-C- Immortal Porpoises(矩阵)

来源:互联网 发布:网络教育教学 编辑:程序博客网 时间:2024/06/10 23:03

点击打开题目

题目描述:就是斐波拉契数列,但是n会很大 2^48再对10e9取余,所以就不可以简单递推了

用到了矩阵相乘矩阵快速幂

题解:斐波拉契数列 :Fn=Fn-1+Fn-2 

矩阵 |Fn-1 Fn-2| 乘以一个什么样的矩阵可以变为 | Fn  Fn-1| 呢?根据矩阵乘法可知为:

|1 1|

|1 0|,暂记为 a。其他题目也应该这样想,重点求这个可以用数字表示的矩阵。

|F2 F1|*a=|F3 F2|......类推可知 |Fn+1 Fn|=|F2 F1|*a^(n-1)

这样写出矩阵乘法和快速幂就可以求出 Fn。输出最后 ans.m[1][2]即可。


#include <cstdio>#include <stack>#include <queue>#include <cmath>#include <vector>#include <cstring>#include <algorithm>using namespace std;#define CLR(a,b) memset(a,b,sizeof(a))#define INF 0x3f3f3f3f#define LL long longconst LL MOD = 1e9;struct Matrix{LL m[5][5];int h,w;};Matrix Matrix_multiply(Matrix a,Matrix b)//矩阵相乘 {Matrix c;c.h=a.h;c.w=b.w;CLR(c.m,0);//初始化 for(int i=1;i<=a.h;i++){for(int j=1;j<=a.w;j++){if(a.m[i][j]==0)continue;for(int k=1;k<=b.w;k++)c.m[i][k]=(c.m[i][k]+a.m[i][j]*b.m[j][k]%MOD)%MOD;}}return c;}Matrix Quick(Matrix now,LL n)// now 矩阵的 n 次方,用快速幂 {Matrix res;//保存n次后的结果,就像普通快速幂的 ans res.h=now.h;res.w=now.w;CLR(res.m,0);for(int i=1;i<=res.h;i++)res.m[i][i]=1;while(n){if(n&1)res=Matrix_multiply(res,now);now=Matrix_multiply(now,now);n>>=1;}return res;}int main(){int u;scanf("%d",&u);while(u--){int k;LL n;scanf("%d %lld",&k,&n);Matrix ori,pr,ans;ori.h=ori.w=2;CLR(ori.m,0);ori.m[1][1]=ori.m[1][2]=ori.m[2][1]=1,ori.m[2][2]=0;pr.h=1,pr.w=2;CLR(pr.m,0);pr.m[1][1]=pr.m[1][2]=1;ans=Matrix_multiply(pr,Quick(ori,n-1));printf("%d %lld\n",k,ans.m[1][2]);}return 0;}


0 0
原创粉丝点击