佳佳对数学,尤其对数列十分感兴趣。在研究完 Fibonacci 数列后,他创造出许多稀奇古怪的数列。例如用 S(n)S(n)
表示 Fibonacci 前 nn
项和 modmmodm
的值,即 S(n)=(F1+F2+…+Fn)modmS(n)=(F1+F2+…+Fn)modm
,其中 F1=F2=1,Fi=Fi−1+Fi−2F1=F2=1,Fi=Fi−1+Fi−2
。可这对佳佳来说还是小菜一碟。终于,她找到了一个自己解决不了的问题。用 T(n)=(F1+2F2+3F3+…+nFn)modmT(n)=(F1+2F2+3F3+…+nFn)modm
表示 Fibonacci 数列前 nn
项变形后的和 modmmodm
的值。现在佳佳告诉你了一个 nn
和 mm
,请求出 T(n)T(n)
的值。输入格式共一行,包含两个整数 nn
和 mm
。输出格式共一行,输出 T(n)T(n)
的值。数据范围1≤n,m≤231−11≤n,m≤231−1
输入样例:5 5
输出样例:1
样例解释T(5)=(1+2×1+3×2+4×3+5×5)mod5=1
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long LL;
const int N = 4;
int n, m;
void mul(int c[][N], int a[][N], int b[][N]){
static int t[N][N];
memset(t, 0, sizeof t);
for (int i = 0; i < N; i ++)
for (int j = 0; j < N; j ++)
for (int k = 0; k < N; k ++)
t[i][j] = (t[i][j] + (LL)a[i][k] * b[k][j]) % m;
memcpy(c, t, sizeof t);
}
int main(){
cin >> n >> m;
int f1[N][N] = {1, 1, 1, 0};
int a[N][N] = {
{0, 1, 0, 0},
{1, 1, 1, 0},
{0, 0, 1, 1},
{0, 0, 0, 1},
};
int k = n - 1;
while(k){
if (k & 1) mul(f1, f1, a);
mul(a, a, a);
k >>= 1;
}
cout << (((LL)n * f1[0][2] - f1[0][3]) % m + m) % m << endl;
return 0;
}