佳佳對數學,尤其對數列十分感興趣。
在研究完 Fibonacci 數列後,他創造出許多稀奇古怪的數列。
例如用 S(n) 表示 Fibonacci 前 n 項和 modm 的值,即 S(n)=(F1+F2+…+Fn)modm,其中 F1=F2=1,Fi=Fi−1+Fi−2。
可這對佳佳來說還是小菜一碟。
終於,她找到了一個自己解決不了的問題。
用 T(n)=(F1+2F2+3F3+…+nFn)modm 表示 Fibonacci 數列前 n 項變形後的和 modm 的值。
現在佳佳告訴你了一個 n 和 m,請求出 T(n) 的值。
輸入格式
共一行,包含兩個整數 n 和 m。
輸出格式
共一行,輸出 T(n) 的值。
數據範圍
1≤n,m≤231−1
輸入樣例:
5 5
輸出樣例:
1
樣例解釋
T(5)=(1+2×1+3×2+4×3+5×5)mod5=1
解析:
Fn =
Fn+1 =
設Pn=nSn-Tn
Tn =nSn-Pn
Pn+1 = (n+1)Sn+1-Tn+1
*
=
* (n-1)
=
因爲我們求出的是Pn,所以最終答案Tn=n*Sn-Pn
#include<bits/stdc++.h >
using namespace std;
typedef long long ll;
ll n, MOD;
struct lxw
{
ll res[4][4];
}base,node;
lxw multi(lxw a,lxw b)
{
lxw tmp;
memset(tmp.res,0,sizeof tmp.res);
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
for(int k=0;k<4;k++)
tmp.res[i][j]=(tmp.res[i][j]+a.res[i][k]*b.res[k][j])%MOD;
return tmp;
}
int main()
{
cin>>n>>MOD;
ll x=n;
node.res[0][0]=1;node.res[0][1]=1;node.res[0][2]=1;
base.res[0][1]=base.res[1][0]=base.res[1][1]=base.res[1][2]=base.res[2][2]=base.res[2][3]=base.res[3][3]=1;
n=n-1;
while(n)
{
if(n&1) node=multi(node,base);
base=multi(base,base);
n>>=1;
}
cout<<((x*node.res[0][2]-node.res[0][3])%MOD+MOD)%MOD<<endl;
}