#题意
フィボナッチの最初のn項の合計を求めます
1≤n≤2 10
# 説明
広いデータ範囲はO(√n)またはO(log n)のみを受け入れることができます
行列の再帰が高速化、F(n)3次元ベクトル表現{f(n)、f(n + 1)、s(n)}
乗算行列
0 1 0
A = 1 1 1
0 0 1
つまり、F(0)・A n
速い力はO(3 3 logn)に達することができます
1 #include <bits / stdc ++。h>
2 #define ll long long
3 using namespace std;
4 const int N = 2e6;
5 int n、mod;
6 void mul(int f [ 3 ]、int a [ 3 ] [ 3 ]){
7 int c [ 3 ];
8 memset(c、0、sizeof c);
9 for(int i = 0 ; i < 3 ; i ++)
10 for(int k = 0 ; k < 3 ; k ++ )
11 c [i] =(c [i] +((ll)f [k] * a [k] [i])%mod)%mod;
12 memcpy(f、c、sizeof c);
13 }
14 void mulself(int a [ 3 ] [ 3 ]){
15 int c [ 3 ] [ 3 ];
16 memset(c、0、sizeof c);
17 for(int i = 0 ; i <3 ; I ++ ){
18 のために(INT J = 0 ; J < 3 ; J ++ )
19 のための(int型のk = 0 ; K < 3 ; K ++ )
20 C [i]は[J] =(C [I] [J] +( ll)a [i] [k] * a [k] [j])%mod;
21 }
22 memcpy(a、c、sizeof c);
23 }
24 int main(){
25 cin >> n >> mod;
26 int a [ 3 ] [ 3 ] = {
27 { 0、1、0 }、
28 { 1、1、1 }、
29 { 0、0、1 }
30 }。
31 int型の F [ 3 ] = { 0、1、0 }。
32 while (n){
33 if(n&1 )mul(f、a);
34 mulself(a);
35 n >> = 1 ;
36 }
37 cout << f [ 2 ] << endl;
38 }