佳佳对数学,尤其对数列十分感兴趣。
在研究完 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 =
[
f
n
f
n
+
1
S
n
P
n
]
\begin{bmatrix}fn & fn+1 &Sn & Pn\end{bmatrix}
[fnfn+1SnPn]
Fn+1 =
[
f
n
+
1
f
n
+
2
S
n
+
1
P
n
+
1
]
\begin{bmatrix}fn+1 & fn+2 & Sn+1 & Pn+1\end{bmatrix}
[fn+1fn+2Sn+1Pn+1]
设Pn=nSn-Tn
Tn =nSn-Pn
Pn+1 = (n+1)Sn+1-Tn+1
[ f n f n + 1 S n P n ] \begin{bmatrix}fn & fn+1 &Sn & Pn\end{bmatrix} [fnfn+1SnPn] * [ 0 1 0 0 1 1 1 0 0 0 1 1 0 0 0 1 ] \begin{bmatrix}0 & 1& 0 & 0\\1 & 1 &1 & 0\\0 & 0 & 1 &1\\0 &0 & 0 & 1\end{bmatrix} ⎣⎢⎢⎡0100110001100011⎦⎥⎥⎤
= [ f n + 1 f n + 2 S n + 1 P n + 1 ] \begin{bmatrix}fn+1 & fn+2 & Sn+1 & Pn+1\end{bmatrix} [fn+1fn+2Sn+1Pn+1]
[ 1 1 1 0 ] \begin{bmatrix}1 & 1 &1& 0\end{bmatrix} [1110] * [ 0 1 0 0 1 1 1 0 0 0 1 1 0 0 0 1 ] \begin{bmatrix}0 & 1& 0 & 0\\1 & 1 &1 & 0\\0 & 0 & 1 &1\\0 &0 & 0 & 1\end{bmatrix} ⎣⎢⎢⎡0100110001100011⎦⎥⎥⎤ (n-1)
= [ f n + 1 f n + 2 S n + 1 P n + 1 ] \begin{bmatrix}fn+1 & fn+2 & Sn+1 & Pn+1\end{bmatrix} [fn+1fn+2Sn+1Pn+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;
}