蓝桥杯 试题 算法提高 新型斐波那契数列

原题
分析:n过大,直接求会超时,所以观察出规律,用快速幂求解。
在这里插入图片描述
在这里插入图片描述

易错点

注意初始化,结构体中的数组没有初始化
以及函数忘记写返回值,devc不报错,经常忘记


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n; 
ll m;
typedef struct matrix{
	ll mat[4][4];
}matrix;
matrix a;
matrix init(matrix t)
{
	for (int i=1;i<=3;i++){
		for (int j=1;j<=3;j++){
			t.mat[i][j]=0;
		}
	}
	return t;
}
matrix modpow(matrix b,ll p){
	
	if (p==1){
		return b;
	}
	matrix tp;
	tp=init(tp);
	matrix t=modpow(b,p/2);
	for (int i=1;i<=3;i++){
			for (int j=1;j<=3;j++){
				for (int k=1;k<=3;k++){
					tp.mat[i][j]+=(t.mat[i][k]*t.mat[k][j])%m;
					tp.mat[i][j]%=m;
				}
			}
		}
	
	matrix ans;
	ans=init(ans);
	if (p%2==1){
		for (int i=1;i<=3;i++){
			for (int j=1;j<=3;j++){
				for (int k=1;k<=3;k++){
					ans.mat[i][j]+=(tp.mat[i][k]*b.mat[k][j])%m;
					ans.mat[i][j]%=m;
				}
			}
		}
		return ans;
	}
	else{
		return tp;
	}
}
int main()
{
	matrix tt;
	
	cin>>n>>m;
	if (n==1 || n==2 || n==3){
		cout<<1;
		return 0;
	}
	a.mat[1][1]=0;a.mat[1][2]=1;a.mat[1][3]=0;
	a.mat[2][1]=0;a.mat[2][2]=0;a.mat[2][3]=1;
	a.mat[3][1]=1;a.mat[3][2]=1;a.mat[3][3]=1;
	//cout<<11<<endl;
	matrix ans=modpow(a,n-3);
	//cout<<22<<endl;
	cout<<((ans.mat[3][1]+ans.mat[3][2])%m+ans.mat[3][3])%m;
	/*
	for (int i=1;i<=3;i++){
		for (int j=1;j<=3;j++){
			cout<<ans.mat[i][j]<<" ";
		}
		cout<<endl;
	}
	
	*/
	return 0;
}

/*
100 7
4  3
5  5
6  2
7  3
8  3
9  1
10  0
11  4
12  5
13  2
14  4
15  4
16  3
17  4
18  4
19  4
20  5
21  6
22  1
23  5
24  5
25  4
26  0
27  2
28  6
29  1
30  2
31  2
32  5
33  2
34  2
35  2
36  6
37  3
38  4
39  6
40  6
41  2
42  0
43  1
44  3
45  4
46  1
47  1
48  6
49  1
50  1
51  1
52  3
53  5
54  2
55  3
56  3
57  1
58  0
59  4
60  5
61  2
62  4
63  4
64  3
65  4
66  4
67  4
68  5
69  6
70  1
71  5
72  5
73  4
74  0
75  2
76  6
77  1
78  2
79  2
80  5
81  2
82  2
83  2
84  6
85  3
86  4
87  6
88  6
89  2
90  0
91  1
92  3
93  4
94  1
95  1
96  6
97  1
98  1
99  1
100  3

*/ 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值