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<=231−1)
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;
}