原文地址:
Anotherkind of Fibonacci
Time Limit: 3000/1000 MS(Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 802 Accepted Submission(s): 326
Problem Description
As we all known , the Fibonacci series : F(0)= 1, F(1) = 1, F(N) = F(N - 1) + F(N - 2) (N >= 2).Now we define anotherkind of Fibonacci : A(0) = 1 , A(1) = 1 , A(N) = X * A(N - 1) + Y * A(N - 2) (N>= 2).And we want to Calculate S(N) , S(N) = A(0)2 +A(1)2+……+A(n)2.
Input
Thereare several test cases.
Each test case will contain three integers , N, X , Y .
N : 2<= N <= 231 – 1
X : 2<= X <= 231– 1
Y : 2<= Y <= 231 – 1
Output
Foreach test case , output the answer of S(n).If the answer is too big , divide itby 10007 and give me the reminder.
Sample Input
2 1 1
3 2 3
Sample Output
6
196
下为解题报告:林大陈宇
该题为矩阵连乘问题,主要考虑以下公式:
f(n)=x*f(n-1)+y*f(n-2)
先看 s(n)=s(n-1)+f(n)^2;
右边出现了n,不可以的,只能出现n-1 或n-2
所以:s(n-1)=s(n-2)+f(n-1)^2; 右边有2项,s(n-2)和f(n-1)^2必须要有了
S(n-2)-----------às(n-1)
F(n-1)^2------à f(n)^2=[xf(n-1)+yf(n-2)]^2=出现了f(n-2)^2和2xyf(n-1)f(n-2),所以共4项
最左边是1个空的矩阵(4*4),也是我们要构造的矩阵(只要学过矩阵的人,就能把它算出来了吧)
然后代入矩阵连乘幂的模板算下就行了(该模板要会背着敲)
#include <iostream>
#include <stdio.h>
#include <cstring>
#define Mod 10007
using namespace std;
const int MAX = 4;
typedef struct{
int m[MAX][MAX];
} Matrix;
MatrixP={1,1,0,0,
0,0,0,0,
0,1,0,0,
0,0,0,0};
MatrixI={1,0,0,0,
0,1,0,0,
0,0,1,0,
0,0,0,1};
Matrixmatrixmul(Matrix a,Matrix b) //矩阵乘法
{
int i,j,k;
Matrix c;
for (i = 0 ; i < MAX; i++)
for (j = 0;j < MAX;j++)
{
c.m[i][j] = 0;
for (k = 0; k < MAX; k++)
c.m[i][j] += (a.m[i][k]*b.m[k][j])%Mod;
c.m[i][j] %= Mod;
}
return c;
}
Matrix quickpow(long long n)
{
Matrix m = P, b = I;
while (n >= 1)
{
if (n & 1)
b = matrixmul(b,m);
n = n >> 1;
m =matrixmul(m,m);
}
return b;
}
int main()
{
int n,x,y,sum;
Matrix b;
/ while(cin>>n>>x>>y)
{
sum=0;
x=x%Mod;
y=y%Mod;
P.m[1][1]=(x*x)%Mod;P.m[1][2]=(y*y)%Mod;P.m[1][3]=(2*x*y)%Mod;
P.m[3][1]=x;P.m[3][3]=y;
b=quickpow(n);
for(int i=0;i<4;i++)
sum+=b.m[0][i]%Mod;
cout<<sum%Mod<<endl;
}
return 0;
}
注意: 注意每一步都要取模,别怕麻烦;
对于x和y要是取负数的话(本题没有),则要(data%mod+mod)%mod;
正的就直接data%mod就行;
typedef struct{
int m[MAX][MAX];
} Matrix;
该结构体的定义要注意,若将int 类型换成long long ,则运行时间会翻倍,可能会TLE,注意哦
----------------------------------------------------------------------------------------------------------------------
有兴趣的同学可以接着看,很有收获的,下面的方法和我的类似,我是把够造矩阵A放在左边,它是放在中间的,请用我的方法推1下,我给答案了。
构造常系数矩阵!
(一)Fibonacci数列f[n]=f[n-1]+f[n-2],f[1]=f[2]=1的第n项的快速求法(不考虑高精度).
解法:
考虑1×2的矩阵【f[n-2],f[n-1]】。根据fibonacci数列的递推关系,我们希望通过乘以一个2×2的矩阵,得到矩阵【f[n-1],f[n]】=【f[n-1],f[n-1]+f[n-2]】
很容易构造出这个2×2矩阵A,即:
01
11
所以,有【f[1],f[2]】×A=【f[2],f[3]】
又因为矩阵乘法满足结合律,故有:
【f[1],f[2]】×A n-1=【f[n],f[n+1]】
这个矩阵的第一个元素即为所求。
至于如何快速求出A n-1,相信大家都会,即递归地:n为偶数时,An=(A n/2)2;n为奇数时,An=(A n/2)2*A。
问题(一)解决。
我的方法: (a)
还是填空:
还没会吗? (a)式中左边的空矩阵就是让你填的A
(二)数列f[n]=f[n-1]+f[n-2]+1,f[1]=f[2]=1的第n项的快速求法(不考虑高精度).
解法:
仿照前例,考虑1×3的矩阵【f[n-2],f[n-1],1】,希望求得某3×3的矩阵A,使得此1×3的矩阵乘以A得到矩阵:【f[n-1],f[n],1】=【f[n-1],f[n-1]+f[n-2]+1,1】
容易构造出这个3×3的矩阵A,即:
010
110
011
问题(二)解决。
我的推法:
A是3*3的矩阵,填空吧
(三)数列f[n]=f[n-1]+f[n-2]+n+1,f[1]=f[2]=1的第n项的快速求法(不考虑高精度).
解法:
仿照前例,考虑1×4的矩阵【f[n-2],f[n-1],n,1】,希望求得某4×4的矩阵A,使得此1×4的矩阵乘以A得到矩阵:
【f[n-1],f[n],n+1,1】=【f[n-1],f[n-1]+f[n-2]+n+1,n+1,1】
容易构造出这个4×4的矩阵A,即:
0100
1100
0110
0111
问题(三)解决……
我自己的推法
接着填空:
四)数列f[n]=f[n-1]+f[n-2],f[1]=f[2]=1的前n项和s[n]的快速求法(不考虑高精度).
解法:
虽然我们有S[n]=F[n+2]-1,但本文不考虑此方法,我们想要得到更一般的方法。
考虑(一)的矩阵A,容易发现我们要求【f[1],f[2]】×(A+A2+A3+…+AN-1)。很多人使用一种很数学的方法构造一个2r*2r(r是A的阶数,这里为2)的矩阵来计算,这种方法比较麻烦且很慢,这里不再介绍。下面考虑一种新方法。
仿照之前的思路,考虑1×3的矩阵【f[n-2],f[n-1],s[n-2]】,我们希望通过乘以一个3×3的矩阵A,得到1×3的矩阵:
【f[n-1],f[n],s[n-1]】=【f[n-1],f[n-1]+f[n-2],s[n-2]+f[n-1]】
容易得到这个3×3的矩阵是:
010
111
001
然后…………容易发现,这种方法的矩阵规模是(r+1)*(r+1),比之前流行的方法好得多。
我用分块矩阵做过这题,但该方法的确应该推广,是主流的思想。
我的推法:
,所以矩阵见下,填空
为所求
(五)数列f[n]=f[n-1]+f[n-2]+n+1,f[1]=f[2]=1的前n项和s[n]的快速求法(不考虑高精度).
解法:
结合(三)(四),容易想到……
考虑1×5的矩阵【f[n-2],f[n-1],s[n-2],n,1】,
我们需要找到一个5×5的矩阵A,使得它乘以A得到如下1×5的矩阵:
【f[n-1],f[n],s[n-1],n+1,1】
=【f[n-1], f[n-1]+f[n-2]+n+1,s[n-2]+f[n-1],n+1,1】
容易构造出A为:
01000
11100
00100
01010
01011
然后……问题解决。
我的推法:
,填空
为构造的矩阵。
陈宇于2012年7月15日