「一本通 6.5 例 4」佳佳的 Fibonacci

题目描述

佳佳对数学,尤其对数列十分感兴趣。在研究完 Fibonacci 数列后,他创造出许多稀奇古怪的数列。例如用 S(n) 表示 Fibonacci 前 n 项和  mod m 的值,即 S(n)=(F1+F2+...+Fn) mod m,其中 F1=F2=1, Fi=Fi-1+Fi-2。可这对佳佳来说还是小菜一碟。

终于,她找到了一个自己解决不了的问题。用 T(n)=(F1+2F2+3F3+...+nFn) mod m 表示 Fibonacci 数列前 n 项变形后的和  mod m 的值。

现在佳佳告诉你了一个 n 和 m,请求出 T(n) 的值。

输入输出格式

输入格式:

输入数据包括一行,两个用空格隔开的整数 n,m。

输出格式:

仅一行,T(n) 的值。

题目分析:
 

已知S(n)=F(n+2)-1

则 T(n)=(S(n)+S(n)-S(1)+S(n)-S(2)+...+S(n)-S(n-1))

整理可得T(n)=nS(n)- \sum_{i=1}^{n-1} S(i)

因此T(n)=n*(F(n+2)-1)-\sum_{i=3}^{n+1} (F(i)-1)=n*F(n+2)-n-(S(n+1)-(n+1))=n*F(n+2)-n+F(n+3)+n+1

T(n)=n*F(n+2)-F(n+3)+2

然后就是常规矩阵乘法操作:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll n,p;
struct N{
	ll a[3][3];
}A,A_1;
inline N cheng(N x,N y)
{
	N z;
	memset(z.a,0,sizeof(z.a));
	for(ll i=1;i<=2;i++) for(ll j=1;j<=2;j++) for(ll k=1;k<=2;k++) z.a[i][j]=(z.a[i][j]+x.a[i][k]*y.a[k][j])%p;
	return z;
}
inline N ksm(ll b)
{
	if(b==1) return A;
	N tmp=ksm(b/2);
	if(b&1) return cheng(tmp,cheng(tmp,A));
	return cheng(tmp,tmp);
}
int main()
{
	cin>>n>>p;
	A.a[1][1]=1,A.a[1][2]=1,A.a[2][1]=1,A.a[2][2]=0;
	ll S=n*ksm(n+2).a[1][2]-ksm(n+3).a[1][2]+2;
	cout<<(S+p)%p;
	return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值