首页 > 其他分享 >从蓝桥杯来谈Fibonacci数列

从蓝桥杯来谈Fibonacci数列

时间:2023-05-31 15:31:47浏览次数:52  
标签:return Matrix int getFun 杯来 蓝桥 Fibonacci LL MOD


2014年蓝桥杯的第九题是这样描述的:

    

    给定Fibonacci数列F[],其中

从蓝桥杯来谈Fibonacci数列_java

从蓝桥杯来谈Fibonacci数列_java_02

,求表达式


       

从蓝桥杯来谈Fibonacci数列_java_03


    的值。其中

从蓝桥杯来谈Fibonacci数列_java_04


在讲解这道题之前,我们先来看一个简单版的。题目如下:


题目:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1194


分析:可以看出本题就是直接求

从蓝桥杯来谈Fibonacci数列_#include_05

,虽然这里的

从蓝桥杯来谈Fibonacci数列_java_06

很大,但是

从蓝桥杯来谈Fibonacci数列_ci_07

比较小啊,只到1000,那么实际上

     在Fibonacci数列中有很多有用的性质,比如:


     

从蓝桥杯来谈Fibonacci数列_#include_08


     实际上,这个两个公式的推导过程也比较简单。(两种证明方法:带入公式验证;数学归纳法)

    

     所以,我们可以这样来把原表达式变形,即:


     

从蓝桥杯来谈Fibonacci数列_#include_09

   

      那么,我们继续对

从蓝桥杯来谈Fibonacci数列_ci_10

用同样的方法递归下去,容易得到:


      

从蓝桥杯来谈Fibonacci数列_#include_11


      可以看出,到了这一步,我们就把所有的Fibonacci数列的下标减小了,基本可以直接计算了。

   

      因为

从蓝桥杯来谈Fibonacci数列_ci_12

,所以我们得到

从蓝桥杯来谈Fibonacci数列_java_13



      所以到了这里,本题基本就说完了,只需要预处理前1000个Fibonacci数列即可。代码如下:



import java.io.*;
import java.util.*;
import java.math.BigInteger;

public class Main {
	
	final static int N = 1005;
	static BigInteger F[] = new BigInteger[N];
	
	static void Init(){
		F[0] = BigInteger.ZERO;
		F[1] = BigInteger.ONE;
		for(int i=2;i<N;i++)
			F[i] = F[i-1].add(F[i-2]);
	}
	
	public static void main(String[] args){
		Init();
		Scanner cin = new Scanner(System.in);
		int T = cin.nextInt();
		while(T-- != 0){
			long n = cin.nextLong();
			int k = cin.nextInt();
			int x = (int)(n % k);
			long y = n / k;
			int sign = 1;
			if((k & 1) == 1)
				sign = -1;
			BigInteger ans = F[x];
			
			if(sign == 1){
				if((y & 1L) == 1L)
					ans = ans.multiply(F[k-1]);
			}
			else{
				if((y & 1L) == 1L)
					ans = ans.multiply(F[k-1]);
				y >>= 1;
				if((y & 1L) == 1L) 
					ans = ans.multiply(F[k].subtract(BigInteger.ONE));
			}
			System.out.println(ans.mod(F[k]));
		}
	}
}




完美解出上题后,我们来看2014年蓝桥杯的C++ A组的第九题,题目描述在文章开始处。


可以看出本题的难点在于

从蓝桥杯来谈Fibonacci数列_ci_14

很大,所以导致

从蓝桥杯来谈Fibonacci数列_ci_15

也会很大,当然求和的那部分是很简单的。


因为

从蓝桥杯来谈Fibonacci数列_ci_16

,那么就有



从蓝桥杯来谈Fibonacci数列_#include_17

 

所以我们可以把原问题简单模型化为求

从蓝桥杯来谈Fibonacci数列_java_18



 

经过上面简单版题目的介绍,我们知道

 

从蓝桥杯来谈Fibonacci数列_#include_19

 

又知道

从蓝桥杯来谈Fibonacci数列_ci_20

 

 

那么分

从蓝桥杯来谈Fibonacci数列_java_21

为奇偶情况进行讨论:

 

 

一.

从蓝桥杯来谈Fibonacci数列_java_21

为偶数时    很明显

从蓝桥杯来谈Fibonacci数列_#include_23

,这样我们再分

从蓝桥杯来谈Fibonacci数列_ci_24

为奇偶进行讨论

 

   (1)如果

从蓝桥杯来谈Fibonacci数列_ci_24

为偶数,那么有

从蓝桥杯来谈Fibonacci数列_#include_26

 

   (2)如果

从蓝桥杯来谈Fibonacci数列_ci_24

为奇数,那么有

从蓝桥杯来谈Fibonacci数列_ci_28

 

 

二.

从蓝桥杯来谈Fibonacci数列_java_21

为奇数时

 

    得到

从蓝桥杯来谈Fibonacci数列_java_30

,再继续分

从蓝桥杯来谈Fibonacci数列_ci_24

的奇偶和

从蓝桥杯来谈Fibonacci数列_#include_32

的奇偶情况进行讨论

 

   (1)如果

从蓝桥杯来谈Fibonacci数列_ci_24

为偶数且

从蓝桥杯来谈Fibonacci数列_#include_32

为偶数,那么

从蓝桥杯来谈Fibonacci数列_#include_26

 

   (2)如果

从蓝桥杯来谈Fibonacci数列_ci_24

为偶数且

从蓝桥杯来谈Fibonacci数列_#include_32

为奇数,那么

从蓝桥杯来谈Fibonacci数列_#include_38

 

   (3)如果

从蓝桥杯来谈Fibonacci数列_ci_24

为奇数且

从蓝桥杯来谈Fibonacci数列_#include_32

为偶数,那么

从蓝桥杯来谈Fibonacci数列_ci_28

 

   (4)如果

从蓝桥杯来谈Fibonacci数列_ci_24

为奇数且

从蓝桥杯来谈Fibonacci数列_#include_32

为奇数,那么

从蓝桥杯来谈Fibonacci数列_java_44

 

 

从上面的所有情况来看,难点就在于如何进一步简化

从蓝桥杯来谈Fibonacci数列_ci_45


 

对于这个问题,我们还有另一个性质

 

性质:若

从蓝桥杯来谈Fibonacci数列_java_46

,则

从蓝桥杯来谈Fibonacci数列_#include_47

 

可以看出

从蓝桥杯来谈Fibonacci数列_java_48

,再对比

从蓝桥杯来谈Fibonacci数列_ci_49

,可知

从蓝桥杯来谈Fibonacci数列_#include_50


 

我们令

从蓝桥杯来谈Fibonacci数列_ci_51

,那么利用上述性质,我们替换一下:

从蓝桥杯来谈Fibonacci数列_ci_52

,得到:

 

从蓝桥杯来谈Fibonacci数列_java_53

,变换一下顺序,即

 

从蓝桥杯来谈Fibonacci数列_#include_54

,所以

 

从蓝桥杯来谈Fibonacci数列_#include_55

 

可以看出

从蓝桥杯来谈Fibonacci数列_java_56

,所以再分

从蓝桥杯来谈Fibonacci数列_ci_57

的奇偶性进行讨论:

 

(1)

从蓝桥杯来谈Fibonacci数列_ci_57

为奇数时,

从蓝桥杯来谈Fibonacci数列_#include_59

 

(2)

从蓝桥杯来谈Fibonacci数列_ci_57

为偶数时,

从蓝桥杯来谈Fibonacci数列_java_61

 

到了这里,我们就对

从蓝桥杯来谈Fibonacci数列_java_62

进行了简化,那么再对

从蓝桥杯来谈Fibonacci数列_ci_63

取余用矩阵快速幂解决即可。

 

最后,来看一道类似的题目。描述如下


题目:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1365


代码:


#include <iostream>
#include <string.h>
#include <stdio.h>

using namespace std;
typedef long long LL;
const int N = 2;
const int MOD = 1000000007;

struct Matrix
{
	LL m[N][N];
};

Matrix I = {
	1, 0,
	0, 1
};

Matrix A = {
	1, 1,
	1, 0
};

Matrix multi(Matrix A, Matrix B)
{
	Matrix C;
	for(int i = 0; i < N; i++)
	{
		for(int j = 0; j < N; j++)
		{
			C.m[i][j] = 0;
			for(int k = 0; k < N; k++)
				C.m[i][j] += A.m[i][k] * B.m[k][j];
			C.m[i][j] %= MOD;
		}
	}
	return C;
}

Matrix Power(Matrix A, LL n)
{
	Matrix ans = I, P = A;
	while(n)
	{
		if(n & 1)
		{
			ans = multi(ans, P);
			n--;
		}
		n >>= 1;
		P = multi(P, P);
	}
	return ans;
}

//计算F(n) % MOD
LL getFun(LL n)
{
	Matrix ans = Power(A, n);
	return ans.m[1][0];
}

//计算F(m - 1) * F(n % m) mod F(m)
LL getRes(LL n, LL m)
{
	LL k = n % m;
	if(k & 1)
		return getFun(m - k);
	return ((getFun(m) - getFun(m - k)) % MOD + MOD) % MOD;
}

LL Solve(LL n, LL m)
{
	LL t1 = n / m;
	if(m & 1)
	{
		LL t2 = t1 >> 1;
		if(t1 % 2 == 0 && t2 % 2 == 0)
			return getFun(n % m);
		if(t1 % 2 == 0 && t2 % 2 == 1)
			return ((getFun(m) - getFun(n % m)) % MOD + MOD) % MOD;
		if(t1 % 2 == 1 && t2 % 2 == 0)
			return getRes(n, m);
		if(t1 % 2 == 1 && t2 % 2 == 1)
			return ((getFun(m) - getRes(n, m)) % MOD + MOD) % MOD;
	}
	else
	{
		if(t1 & 1)
			return getRes(n, m);
		else
			return getFun(n % m);
	}
}

LL getResponse(LL n, LL m)
{
//	n += 2;
	LL res = Solve(n, m);
//	if(res == 0)
//		return getFun(m) - 1;
//	return res - 1;
	return res;
}

int main()
{
	int T;
	scanf("%d", &T);
	while(T--)
	{
		LL n, k;
		scanf("%lld %lld", &n, &k);
		printf("%lld\n", getResponse(n, k));
	}
	return 0;
}





标签:return,Matrix,int,getFun,杯来,蓝桥,Fibonacci,LL,MOD
From: https://blog.51cto.com/u_16146153/6387423

相关文章

  • [蓝桥杯 2022 省 B] 扫雷
    [蓝桥杯2022省B]扫雷题目描述小明最近迷上了一款名为《扫雷》的游戏。其中有一个关卡的任务如下,在一个二维平面上放置着 n 个炸雷,第 2023-05-31i 个炸雷 (,,)(xi​,yi​,ri​) 表示在坐标 (,)(xi​,yi​) 处存在一个炸雷,它的爆炸范围是以半径为 ri​ 的一个圆。......
  • 初见蓝桥杯
    由于我怕我太菜所以大一没报蓝桥杯比赛(我这个人很自卑呜呜呜)P8637[蓝桥杯2016省B]交换瓶子题目描述有 N 个瓶子,编号 1∼N,放在架子上。比如有 55 个瓶子:2,1,3,5,4要求每次拿起 22 个瓶子,交换它们的位置。经过若干次后,使得瓶子的序号为:1,2,3,4,5对于这么简......
  • 蓝桥杯 基础练习 特殊回文数(C++)
    资源限制内存限制:512.0MBC/C++时间限制:1.0sJava时间限制:3.0sPython时间限制:5.0s问题描述123321是一个非常特殊的数,它从左边读和从右边读是一样的。输入一个正整数n,编程求所有这样的五位和六位十进制数,满足各位数字之和等于n。输入格式输入一行,包含一个正整......
  • 第十四届蓝桥杯大赛青少组全国总决赛初级组C++C++题解
    第十四届蓝桥杯大赛青少组全国总决赛初级组\(C++\)题解第一题给定一个十进制正整数\(N(1≤N≤10^9)\),请从小到大输出\(1\)~\(N\)之间(含\(1\)和\(N\))所有满足以下要求的数:这个数转换为八进制后是一个回文数;这个数是一个平方数。例如:\(N=20\),在\(1\)~\(20\)之间满足要求......
  • 【蓝桥杯集训·每日一题】AcWing 4496. 吃水果
    写在前面本人CSDN博客主页:这里一、题目1、原题链接4496.吃水果2、题目描述n个小朋友站成一排,等着吃水果。一共有m种水果,每种水果的数量都足够多。现在,要给每个小朋友都发一个水果,要求:在所有小朋友都拿到水果后,恰好有k个小朋友拿到的水果和其左边相邻小朋友拿到的水果不同(最左......
  • 第十二届蓝桥杯c++b组国赛题解(还在持续更新中...)
    试题A:带宽解题思路:由于小蓝家的网络带宽是200Mbps,即200Mb/s,所以一秒钟可以下载200Mb的内容,根据1B=8b的换算规则,所以200Mb=200/8MB=25MB。所以小蓝家的网络理论上每秒钟最多可以从网上下载25MB的内容。代码实现:#include<iostream>#include<algorithm>usingnamespacestd......
  • 【蓝桥杯 2019 省 A】修改数组【并查集】
    链接https://www.luogu.com.cn/problem/P8686题意给你\(n\)个数a[1...n],从\(a_2\)开始,如果和之前的某个数具有相等的值,就一直让\(a_i=a_i+1\),直到前面的任何一个数都和它不相等\(1\leqn\leq10^5\),\(1\leqa_i\leq10^6\)问最后的序列是什么思路暴力做法......
  • 蓝桥杯----2022国C
    《斐波那契与7》写的时候第一次尝试了暴力,跑了一个小时多都没有跑完查了一下,大概1s可以跑1e8条指令如果真要跑的话 202202011200,应该跑到比赛结束应该内跑完(希望电脑不会炸) 暴力还是不合理的,遇到这种情况试一下循环节对于斐波那契数列Fn=Fn-1+Fn-2所......
  • 【蓝桥杯集训·每日一题】AcWing 4309. 消灭老鼠
    写在前面本人CSDN博客主页:这里一、题目1、原题链接4309.消灭老鼠2、题目描述约翰的农场可以看作一个二维平面。农场中有n个老鼠,在毁坏着农田。第i个老鼠的位置坐标为(xi,yi)。不同老鼠可能位于同一位置。在(x0,y0)处,装有一个双向发射的激光枪,该位置没有老鼠。激光枪每次发......
  • 【蓝桥杯集训·每日一题】AcWing 3625. 幂次方
    写在前面本人CSDN博客主页:这里一、题目1、原题链接3625.幂次方2、题目描述对任意正整数N,计算XNmod233333的值。输入格式共一行,两个整数X和N。输出格式共一行,一个整数,表示XNmod233333的值。数据范围1≤X,N≤109输入样例:25输出样例:32二、解题报告1、思路分析(1)快速幂模板题......