本篇题解用于作者本人对于矩阵乘法的印象加深,也欢迎大家的阅读。


题目大意

众所周知,斐波那契数列为 \(f(0)=1\) , \(f(1)=1\) ,\(f(n)=f(n-1)+f(n-2)~(n>=2)\) 。

定义另一种斐波那契数列: \(A(0)=1\) , \(A(1)=1\) , \(A(n)=x*A(n-1)+y*A(n-2)~(n>=2)\) 。

我们要计算 \(S(n)\) , \(S(n)=A(0)^2+A(1)^2+...+A(n)^2\) 。

题解

我们可以很轻易的发现这是一道矩阵乘法的题,因为他是求关于一个递推式的平方和,而本题的难点就在于如何构建出合适的加速矩阵。

本题求的是 \(S(n)\) ,所以我们可以从 \(S(n)\) 递推式入手。

\[S(n)=S(n-1)+A^2(n)
\]

所以, \(A^2(n)\) 肯定要列入我们的矩阵中。我们再来看看 \(A^2(n)\) 的递推式:

\[\begin{array}{}
A^2(n)=(x*A(n-1)+y*A(n-2))^2\\
\\
=x^2A^2(n-1)+2xyA(n-1)A(n-2)+y^2A^2(n-2)\\
\end{array}
\]

所以, \(A^2(n)\) , \(A(n)A(n-1)\) 和 \(A^2(n-1)\) 也是需要加入矩阵的。因此我们的状态矩阵就是:

\[\left[\begin{matrix}
S(n)&A^2(n)&A^2(n-1)&A(n)A(n-1)\\
\end{matrix}\right]
\]

其中每一个元素的递推式如下:

\[\begin{array}{}
S(n)=S(n-1)+x^2A^2(n-1)+2xyA(n-1)A(n-2)+y^2A^2(n-2)\\
\\
A^2(n)=x^2A^2(n-1)+2xyA(n-1)A(n-2)+y^2A^2(n-2)\\
\\
A^2(n-1)=A^2(n-1)\\
\\
A(n)A(n-1)=xA^2(n-1)+yA(n-1)A(n-2)
\end{array}
\]

我们再根据状态矩阵以及状态矩阵元素的递推式,我们可以求出加速矩阵:

\[\left[\begin{matrix}
1&0&0&0\\
x^2&x^2&1&x\\
y^2&y^2&0&0\\
2xy&2xy&0&y\\
\end{matrix}\right]
\]

即:

\[\begin{array}{}
\left[\begin{matrix}
S(n-1)&A^2(n-1)&A^2(n-2)&A(n-1)A(n-2)\\
\end{matrix}\right]
*
\left[\begin{matrix}
1&0&0&0\\
x^2&x^2&1&x\\
y^2&y^2&0&0\\
2xy&2xy&0&y\\
\end{matrix}\right]
=
\left[\begin{matrix}
S(n)&A^2(n)&A^2(n-1)&A(n)A(n-1)\\
\end{matrix}\right]\\

\end{array}
\]

最后我们再套一个矩阵快速幂的模板就可以了。

代码如下:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int MOD=10007;
struct Matrix
{
int n,m;
ll h[5][5];
Matrix()
{
memset(h,0,sizeof(h));
}
void Re1(int a)
{
n=m=a;
memset(h,0,sizeof(h));
for(int i=1;i<=a;++i)
h[i][i]=1;
}
};
Matrix operator * (const Matrix a,const Matrix b)
{
Matrix ans;
ans.n=a.n;
ans.m=b.m;
for(int i=1;i<=a.n;++i)
{
for(int j=1;j<=b.m;++j)
{
for(int k=1;k<=a.m;++k)
{
ans.h[i][j]+=a.h[i][k]*b.h[k][j]%MOD;
ans.h[i][j]%=MOD;
}
}
}
return ans;
}
Matrix operator ^ (const Matrix xx,const ll kk)
{
Matrix ans,x=xx;
ll k=kk;
ans.Re1(4);
while(k>0)
{
if(k&1)
ans=ans*x;
x=x*x;
k>>=1;
}
return ans;
}
int n;
ll x,y;
Matrix tmp,stp,ans;
int main()
{
tmp.n=1;
tmp.m=4;
tmp.h[1][1]=2;
tmp.h[1][2]=1;
tmp.h[1][3]=1;
tmp.h[1][4]=1;
while(cin>>n>>x>>y)
{
stp.n=stp.m=4;
stp.h[1][1]=stp.h[2][3]=1;
stp.h[2][1]=stp.h[2][2]=x*x%MOD;
stp.h[3][1]=stp.h[3][2]=y*y%MOD;
stp.h[4][1]=stp.h[4][2]=2*x*y%MOD;
stp.h[2][4]=x;
stp.h[4][4]=y;
ans=tmp*(stp^(n-1));
printf("%lld\n",ans.h[1][1]);
}
}

HDU3306 Another kind of Fibonacci的更多相关文章

  1. hdu3306 Another kind of Fibonacci【矩阵快速幂】

    转载请注明出处:http://www.cnblogs.com/KirisameMarisa/p/4187670.html 题目链接:http://acm.hdu.edu.cn/showproblem. ...

  2. HDU3306 Another kind of Fibonacci 矩阵

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - HDU3306 题意概括 A0=1,A1=1,AN=X*AN-1+Y*AN-2(N>=2).求SN,SN ...

  3. HDU3306—Another kind of Fibonacci

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3306 题目意思:一个斐波那契数列的变式,本来是A[n]=A[n-1]+A[n-2],现在变成A[n]= ...

  4. Another kind of Fibonacci(hdu3306)

    Another kind of Fibonacci Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...

  5. hdu3306:Another kind of Fibonacci

    A(0)=A(1)=1,A(i)=X*A(i-1)+Y*A(i-2),求S(n)=A(0)^2+A(1)^2+A(2)^2+A(3)^2+……+A(n)^2. 这个矩阵有点毒.. #include&l ...

  6. 算法与数据结构(九) 查找表的顺序查找、折半查找、插值查找以及Fibonacci查找

    今天这篇博客就聊聊几种常见的查找算法,当然本篇博客只是涉及了部分查找算法,接下来的几篇博客中都将会介绍关于查找的相关内容.本篇博客主要介绍查找表的顺序查找.折半查找.插值查找以及Fibonacci查找 ...

  7. #26 fibonacci seqs

    Difficulty: Easy Topic: Fibonacci seqs Write a function which returns the first X fibonacci numbers. ...

  8. 关于java的递归写法,经典的Fibonacci数的问题

    经典的Fibonacci数的问题 主要想展示一下迭代与递归,以及尾递归的三种写法,以及他们各自的时间性能. public class Fibonacci { /*迭代*/ public static ...

  9. 斐波拉契数列(Fibonacci) 的python实现方式

    第一种:利用for循环 利用for循环时,不涉及到函数,但是这种方法对我种小小白来说比较好理解,一涉及到函数就比较抽象了... >>> fibs = [0,1] >>&g ...

随机推荐

  1. Java字符类型(详解)

    [1]Java中使用单引号来表示字符常量,字符型在内存中占2个字节. char 类型用来表示在Unicode编码表中的字符.Unicode编码被设计用来处理各种语言的文字,它占2个字节,可允许有655 ...

  2. Hive 报错 Failed to load class "org.slf4j.impl.StaticLoggerBinder".

    打开hive报错 SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder". SLF4J: Defaultin ...

  3. Spring源码理论

    Spring Bean的创建过程: Spring容器获取Bean和创建Bean都会调用getBean()方法. getBean()方法 1)getBean()方法内部最终调用doGetBean()方法 ...

  4. Java 添加、读取、删除Excel中的图表趋势线

    本文以Java示例介绍如何在Excel中添加趋势线,以及读取趋势线公式.通过文中的方法可支持添加6种不同类型的趋势线,包括Linear.Exponential.Logarithmic.Moving A ...

  5. 攻克solo第五课(Mixolydian 音阶)

    相对于独奏来说,我们已经说过了很多关于solo或独奏的乐理和技巧.那么这篇文章,笔者将使用guitar pro7软件来跟大家分享Mixolydian 音阶的演奏技巧,以及如何在学习Mixolydian ...

  6. 如何在Visio 中插入各种数学公式?

    在Visio 2007老版本中,插入公式可以直接在插入图片中选择,但是在后来的Visio2013中却无法直接通过插入图片的方法插入,那么该如何在visio 2013中插入公式呢? 具体的操作步骤如下: ...

  7. 简单实用的Boom 3D基础入门教程分享

    Boom 3D可以很大限度的弥补声音设备或是环境的不足,满足您更加高级的声学体验.Boom 3D用简单明了的方式帮助您设计声音,即使您不是专业的声音编辑,也可以达到专业相似的效果. 打开Boom 3D ...

  8. 教你用Vegas Pro制作视频的遮罩转场特效

    很多小伙伴在接触了Vegas之后,都想利用Vegas制作出各种酷炫的特效.小编也是一样. 今天,小编就和大家分享一下,小编近期学会的遮罩转场特效. 首先想要制作遮罩转场效果,需要的素材有:至少两个图片 ...

  9. docker和k8s的概念-IaaS、PaaS、SaaS 的区别

    docker和k8s 参考: 什么是Docker? Kubernetes概述 openstack,docker,mesos,k8s什么关系? IaaS.PaaS.SaaS的概念 SaaS:软件服务,S ...

  10. # 夏普R shv39 0基础精简优化指南

    手机介绍 夏普AQUOS R是目前市面上用户数量和好评数量都非常多的一款产品.它性价比极高,适合各个年龄段的用户选择来满足办公或者家用或者娱乐等不同方面的需求.目前闲鱼价格在400左右,搭载骁龙835 ...