幼儿园数学题I【矩阵乘法】

D e s c r i p t i o n Description Description

某天,幼儿园学生LZH周测数学时吓哭了,一道题都做不出来。这下可麻烦了他马上就会成为垫底的0分啊。他的期望也不高,做出最简单的第一题就够了
题目是这样的,定义

当然为了凸显题目的简单当然不能是小数分数或无理数,a(x)因此需要向下取整,当然求a(n)是非常难的!因此幼儿园园长头皮决定简单一点,求下a(x)的前n项和就行了。

I n p u t Input Input

输入 一个正整数n(保证 1 < = n < = 2 31 − 1 1<=n<=2^{31}-1 1<=n<=2311)

O u t p u t Output Output

输出 一个正整数S(n) 对1000000007 取余就好了
S(n)为前缀和

S a m p l e Sample Sample I n p u t Input Input#1
1
S a m p l e Sample Sample O u t p u t Output Output#1
1
S a m p l e Sample Sample I n p u t Input Input#2
2
S a m p l e Sample Sample O u t p u t Output Output#2
2

T r a i n Train Train o f of of T h o u g h t Thought Thought

那个公式其实就是斐波那契数列
然后用矩阵乘法边算数列边算前缀和

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#define ll long long
using namespace std;

const ll mod = 1000000007;

ll n;

struct wh_
{
    
    
	ll h[10][10];
}Ans, A;

wh_ operator *(wh_ a, wh_ b)//矩阵乘法
{
    
    
	wh_ c;
	memset(c.h, 0, sizeof(c.h));
	for(int i = 1; i <= 4; ++i)
		for(int j = 1; j <= 4; j++)
			for(int k = 1; k <= 4; k++)
				c.h[i][j] = (c.h[i][j] + a.h[i][k] * b.h[k][j] % mod) % mod;
	return c;
}

void power(ll m)//快速幂
{
    
    
	while(m)
	{
    
    
		if(m & 1)Ans = Ans * A;
		A = A * A;
		m >>= 1;
	}
}

int main()
{
    
    
	scanf("%lld", &n);	
	A.h[1][1] = 0, A.h[1][2] = 1, A.h[1][3] = 0;
	A.h[2][1] = 1, A.h[2][2] = 1, A.h[2][3] = 1;
	A.h[3][1] = 0, A.h[3][2] = 0, A.h[3][3] = 1;
	Ans.h[1][1] = 0, Ans.h[1][2] = 1, Ans.h[1][3] = 0;
	power(n);
	printf("%lld", Ans.h[1][3]);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/SSL_wujiajie/article/details/111401995
今日推荐