【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]);
} 


猜你喜欢

转载自blog.csdn.net/kejin2019/article/details/111401045
SSL