1. 程式人生 > 實用技巧 >佳佳的 Fibonacci

佳佳的 Fibonacci

題目描述

佳佳對數學,尤其對數列十分感興趣。在研究完Fibonacci數列後,他創造出許多稀奇古怪的數列。例如用S(n)表示Fibonacci前n項和\bmod mmodm的值,即S(n)=(F_1+F_2+...+F_n) \bmod mS(n)=(F1+F2+...+Fn)modm,其中F_1=F_2=1,F_i=F_{i-1}+F_{i-2}F1=F2=1,Fi=Fi1+Fi2。可這對佳佳來說還是小菜一碟。
終於,她找到了一個自己解決不了的問題。用T(n)=(F_1+2F_2+3F_3+...+nF_n) \bmod mT(n)=(F1+2F2+3F3+...+nFn)modm表示Fibonacci數列前n項變形後的和\bmod mmodm的值。
現在佳佳告訴你了一個n和m,請求出T(n)的值。

輸入描述:

輸入資料包括一行,兩個用空格隔開的整數n,m。

輸出描述:

僅一行,T(n)的值。
示例1

輸入

複製
5 5

輸出

複製
1

說明

T(5)=(1+2 \times1+3 \times2+4 \times3+5 \times5) \bmod5=1T(5)=(1+2×1+3×2+4×3+5×5)mod5=1

備註:

對於30 \%30%的資料,1 \leq n \leq10001n1000;
對於60 \%60%的資料,1 \leq m \leq10001m1000;
對於100 \%100%的資料,1 \leq n,m \leq 2^{31}-11n,m2311。


/*   S(n) = F(n + 2) - 1
T(n) = F(1) + 2F(2) + ... + nF(n)
= nS(n) - (n - 1)F(1) - (n - 2)F(2) - ... - F(n - 1)
= nS(n) - (S(1) + S(2) + ... + S(n - 1))
= nS(n) - (F(3) - 1 + F(4) - 1 + ... + F(n + 1) - 1)
= nS(n) - (F(3) + F(4) + ... + F(n + 1) - n + 1)
= nS(n) - (F(3) + F(4) + ... + F(n + 1)) + n - 1
= n(F(n + 2) - 1) - (F(3) + F(4) + ... + F(n + 1)) + n - 1
= n(F(n + 2) - 1) - (F(1) + F(2) + ... + F(n + 1)) + n - 1 + F(1) + F(2)
= nS(n) - S(n + 1) + n - 1 + F(1) + F(2)
= n(F(n + 2) - 1) - (F(n + 3) - 1) + n - 1 + F(1) + F(2)
= n(F(n + 2) - 1) - (F(n + 3) - 1) + n + 1
= nF(n + 2) - n - F(n + 3) + 1 + n + 1
= nF(n + 2) - F(n + 3) + 2
*/ #include<bits/stdc++.h> using namespace std; void mul(int f[2], int a[2][2], int mod) { int c[2]; memset(c, 0, sizeof(c)); for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { c[i] = (c[i] + (long long)f[j] * a[j][i]) % mod; } } memcpy(f, c, sizeof(c)); } void mulself(int a[2][2], int mod) { int c[2][2]; memset(c, 0, sizeof(c)); for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { for (int k = 0; k < 2; k++) { c[i][j] = (c[i][j] + (long long)a[i][k] * a[k][j]) % mod; } } } memcpy(a, c, sizeof(c)); } int main() { int a[2][2] = {{0, 1}, {1, 1}}; int f[2] = {0, 1}; int aa[2][2] = {{0, 1}, {1, 1}}; int ff[2] = {0, 1}; int n, m; cin >> n >> m; int pa = n + 2, pb = n + 3; while (pa) { if (pa & 1) mul(f, a, m); mulself(a, m); pa >>= 1; } while (pb) { if (pb & 1) mul(ff, aa, m); mulself(aa, m); pb >>= 1; } cout << ((long long)n * f[0] - ff[0] + 2 + m) % m << endl; return 0; }