1. 程式人生 > 其它 >【SSL 2513】幼兒園數學題I【矩陣乘法】

【SSL 2513】幼兒園數學題I【矩陣乘法】

技術標籤:矩陣乘法快速冪

Time Limit:10000MS Memory Limit:65536K
Total Submit:62 Accepted:27
Case Time Limit:1000MS


Description

某天,幼兒園學生LZH周測數學時嚇哭了,一道題都做不出來。這下可麻煩了他馬上就會成為墊底的0分啊。他的期望也不高,做出最簡單的第一題就夠了
題目是這樣的,定義 F ( n ) = ( ( 根 號 5 + 1 ) / 2 ) ( n − 1 ) F(n)=((根號5+1)/2)^(n-1) F(n)=((5+1)/2)(n1) ,當然為了凸顯題目的簡單當然不能是小數分數或無理數, F ( x ) F(x)

F(x)因此需要向上取整,當然求F(n)是非常難的!因此幼兒園園長頭皮決定簡單一點,求下 F ( x ) F(x) F(x)的前n項和就行了。


Input

輸入 一個正整數n(保證 1 < = n < = 2 3 1 − 1 1<=n<=2^31-1 1<=n<=2311

Output

輸出 一個正整數 S ( n ) S(n) S(n) 1000000007 1000000007 1000000007 取餘就好了


樣例

輸入1
1
輸出1
1

輸入2
2
輸出2
2

T i p s : Tips: Tips:暴力找規律


解題思路

矩陣乘法呀

乍一看,一個十分神奇的 ( ( 根 號 5 + 1 ) / 2 ) ( n − 1 ) ((根號5+1)/2)^(n-1)

((5+1)/2)(n1),正準備跳題,然後經大佬說明題目打錯了,其實是斐波那契的遞推式。。。
然後打一波之前的 求斐波那契數列前n項的和 直接過了
在這裡插入圖片描述


程式碼

#include<algorithm>
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
const long long INF=1000000007;
long long n;
struct c{
	long long n,m;
	long long a[
10][10]; }A,B,CC; c operator *(c A,c B){ c 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.a[i][j]=0; for(int k=1;k<=A.m;k++) for(int i=1;i<=C.n;i++) for(int j=1;j<=C.m;j++) C.a[i][j]=(C.a[i][j]+(A.a[i][k]*B.a[k][j]%INF))%INF; return C; } void poww(long long x){ if(x==1) { B=A; return ; } poww(x/2); B=B*B; if(x&1) B=B*A; } int main(){ scanf("%lld",&n); if(n==1) { printf("1"); return 0; } A.n=3,A.m=3; A.a[1][1]=0,A.a[1][2]=1,A.a[1][3]=0; A.a[2][1]=1,A.a[2][2]=1,A.a[2][3]=1; A.a[3][1]=0,A.a[3][2]=0,A.a[3][3]=1; poww(n-1); CC.n=1,CC.m=3; CC.a[1][1]=1,CC.a[1][2]=1,CC.a[1][3]=1; CC=CC*B; printf("%lld",CC.a[1][3]); }