[SSL 1529] [洛谷P1962] Fibonacci sequence [matrix multiplication]

Topic background

Everyone knows that the Fibonacci sequence is a sequence that satisfies the following properties:

F n = 1 ( n ≤ 2 ) F_n= 1 (n≤2) Fn=1(n2)

F n − 1 + F n − 2 ( n ≥ 3 ) F_{n−1} +F_{n−2}(n≥3) Fn1+Fn2(n3)

Title description

Please find F n F_nFn m o d mod mod 1 0 9 + 7 10^9+7 109+The value of 7 .

Input format

One positive integer nn per linen

Output format

Output an integer on a line to indicate the answer.

Sample input and output

Enter #1

5

Output #1

5

Input #2

10

Output #2

55

School OJ:

Subject requires consistent mod modm o d changed to10000 1000010000
Sample Input

123456789

Sample Output

4514

analysis:

已知 f n = f n − 1 + f n − 2 f_n=f_{n-1}+f_{n-2} fn=fn1+fn2
Consider the original 1 ∗ 2 1*212 matrixfi − 2 fi − 1 f_ {i-2} f_ {i-1}fi2fi1
We want a matrix repeatedly to it by Recursive the back of the item
that is desired by the matrix after
fi - 1, fi = fi - 1, fi - 2 + fi - 1 f_ {i-1}, f_ {i} =f_{i-1},f_{i-2}+f_{i-1}fi1,fi=fi1,fi2+fi1
Get this matrix base baseb a s e is
0, 1 0, 10,1

1 , 1 1,1 1,1 The
associative law of matrix multiplicationgives
[f 1, f 2] ∗ basen − 1 = [fn, fn − 1] [f_1,f_2]*base^{n-1}=[f_n,f_{n-1}][f1,f2]basen1=[fn,fn1]
So the requestedfn f_nfnIs the first item

CODE:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int mod=1e9+7;
long long n;
struct matrix{
    
    
	long long n,m;
	long long G[11][11];
}base,A,B;
matrix operator *(matrix a,matrix b)
{
    
    
	matrix C;
	C.n=a.n;C.m=b.m;
	for(int i=1;i<=C.n;i++)
		for(int j=1;j<=C.m;j++)
			C.G[i][j]=0;
	for(int k=1;k<=a.m;k++)
		for(int i=1;i<=a.n;i++)
			for(int j=1;j<=b.m;j++)
				C.G[i][j]=(C.G[i][j]+a.G[i][k]*b.G[k][j]%mod)%mod;  //矩阵乘法
	return C;
}
void ksm(long long x){
    
      //矩阵快速幂
	if(x==1){
    
    
		A=base;
		return;
	}
	ksm(x/2);
	A=A*A;
	if(x&1) A=A*base;
}
int main(){
    
    
	scanf("%lld",&n);
	base.n=2;base.m=2;
	base.G[1][1]=0;base.G[1][2]=1;
	base.G[2][1]=1;base.G[2][2]=1;
	if(n<=2){
    
    
		printf("1");
		return 0;
	}
	else{
    
    
		B.m=2;B.n=1;
		B.G[1][1]=1;B.G[1][2]=1;
		ksm(n-1);
		B=B*A;
		printf("%lld",B.G[1][1]);
	}
	return 0;
}

A mathematical method to find F n F_nFnAnd matrix multiplication the same effect

CODE:

#include<cstdio>
#include<iostream>
#include<map>
using namespace std;
map<long,long>F;
long long n;
const long long mod=10000;
long long f(long long n){
    
    
	if(F.count(n)) return F[n];
	long long k=n/2;
	if(n%2==0)
	{
    
     // n=2*k
		return F[n]=(f(k)*f(k)+f(k-1)*f(k-1))%mod;
	}else{
    
     // n=2*k+1d
		return F[n]=(f(k)*f(k+1)+f(k-1)*f(k))%mod;
	}
} 
int main(){
    
    
	F[0]=F[1]=1;
	scanf("%lld",&n);
	printf("%lld",n==0?0:f(n-1))%mod;
}

Guess you like

Origin blog.csdn.net/dgssl_xhy/article/details/111058830