NOIP模拟 k-斐波那契(矩阵求斐波那契+扩展欧几里得)

博客介绍了如何利用矩阵快速幂和扩展欧几里得算法解决k-斐波那契数列问题。针对30%的数据,通过递推方式求解,复杂度为O(n*P)。对于100%的数据,通过矩阵乘法将复杂度降至O(log n),同时利用扩展欧几里得算法判断不定方程的解,如果gcd(f[n], p) != 1,则无解,输出None。" 78183660,6694756,使用SQLSugar进行事务处理,"['数据库开发', 'ORM框架', 'SQL', 'C#编程', '事务控制']

【题目描述】

    k-斐波那契数列定义如下:

    已知f[n]=1,求【0,P)内所有可能的K。

【输入描述】

    一行两个整数,n和P。

【输出描述】

    从小到大输出所有可能的K,如果没有则输出None。

【输入样例】

5 5

【输出样例】

2

【备注】

对于30%数据,n,P<=1000。

对于100%数据,n, P ≤ 10^9。

 

对于30%的数据,我们可以发现,f[0]=f[1]=k*1,f[2]=f[1]+f[0]=k*2,可以发现k的系数满足斐波那契数列,所以可以直接递推求出f[n]的k的系数,此时问题转换为解f[n]*k≡1(mod p),枚举k,复杂度为O(n*P)。

对于100%的数据,我们发现,对于斐波那契数列f[n]=f[n-1]+f[n-2],改写一下即为f[n]=f[n-1]*1+f[n-2]*1,发现这类似于矩阵乘法,基础矩阵base为{0,1,1,1},第一个矩阵为{1,0,0,1},这样通过矩阵乘法即可计算出fib[n],因为矩阵乘法具有结合律,所以我们可以利用快速幂的思想来解决求fib[n],将复杂度降为O(log n);求解不定方程时,可以利用扩展欧几里得来解决f[n]*k≡1(mod p),由于转化后为f[n]*k+t*p=1,所以任意两个合法k之间至少相差p,所以如果存在可行解,只要调整至[0,p)即可,如果gcd(f[n],p)!=1,那么原不定方程无解,输出None。

贴代码:

#include<bits/
c++# P1058 [NOIP 2008 普及组] 立体图 ## 题目描述 小渊是个聪明的孩子,他经常会给周围的小朋友们讲些自己认为有趣的内容。最近,他准备给小朋友们讲解立体图,请你帮他画出立体图。 小渊有一块面积为 $m \times n$ 的矩形区域,上面有 $m \times n$ 个边长为 $1$ 的格子,每个格子上堆了一些同样大小的积木(积木的长宽高都是 $1$),小渊想请你打印出这些格子的立体图。我们定义每个积木为如下格式,并且不会做任何翻转旋转,只会严格以这一种形式摆放: $$ \def\arraystretch{1e-10} \begin{aligned} &\verb! +---+!\\ &\verb! / /|!\\ &\verb!+---+ |!\quad\textsf{高}\\ &\verb!| | +!\\ &\verb!| |/ !\quad\textsf{宽}\\ &\verb!+---+ !\\ & \quad\textsf{长} \end{aligned}$$ 每个顶点用 $1$ 个加号 `+` 表示,长用 $3$ 个 `-` 表示,宽用 $1$ 个 `/`,高用两个 `|` 表示。字符 `+`,`-`,`/`,`|` 的 ASCII 码分别为 $43$,$45$,$47$,$124$。字符 `.`(ASCII 码 $46$)需要作为背景输出,即立体图里的空白部分需要用 `.` 来代替。立体图的画法如下面的规则: 若两块积木左右相邻,图示为: $$ \def\arraystretch{1e-10} \begin{aligned} \verb!..+---+---+!\\ \verb!./ / /|!\\ \verb!+---+---+ |!\\ \verb!| | | +!\\ \verb!| | |/.!\\ \verb!+---+---+..!\\ \end{aligned} $$ 若两块积木上下相邻,图示为: $$ \def\arraystretch{1e-10} \begin{aligned} \verb!..+---+!\\ \verb!./ /|!\\ \verb!+---+ |!\\ \verb!| | +!\\ \verb!| |/|!\\ \verb!+---+ |!\\ \verb!| | +!\\ \verb!| |/.!\\ \verb!+---+..!\\ \end{aligned} $$ 若两块积木前后相邻,图示为: $$ \def\arraystretch{1e-10} \begin{aligned} \verb!....+---+!\\ \verb!.../ /|!\\ \verb!..+---+ |!\\ \verb!./ /| +!\\ \verb!+---+ |/.!\\ \verb!| | +..!\\ \verb!| |/...!\\ \verb!+---+....!\\ \end{aligned} $$ 立体图中,定义位于第 $(m,1)$ 的格子(即第 $m$ 行第 $1$ 列的格子)上面自底向上的第一块积木(即最下面的一块积木)的左下角顶点为整张图最左下角的点。 ## 输入格式 第一行有用空格隔开的 $2$ 个整数 $m$ 和 $n$,表示有 $m \times n$ 个格子 $(1 \le m,n \le 50)$。 接下来的 $m$ 行,是一个 $m \times n$ 的矩阵,每行有 $n$ 个用空格隔开的整数,其中第 $i$ 行第 $j$ 列上的整数表示第 $i$ 行第 $j$ 列的格子上摞有多少个积木($1 \le $ 每个格子上的积木数 $ \le 100$)。 ## 输出格式 输出包含题目要的立体图,是一个 $K$ 行 $L$ 列的字符串矩阵,其中 $K$ 和 $L$ 表示最少需要 $K$ 行 $L$ 列才能按规定输出立体图。 ## 输入输出样例 #1 ### 输入 #1 ``` 3 4 2 2 1 2 2 2 1 1 3 2 1 2 ``` ### 输出 #1 ``` ......+---+---+...+---+ ..+---+ / /|../ /| ./ /|-+---+ |.+---+ | +---+ |/ /| +-| | + | | +---+ |/+---+ |/| | |/ /| +/ /|-+ | +---+---+ |/+---+ |/| + | | | +-| | + |/. | | |/ | |/| +.. +---+---+---+---+ |/... | | | | | +.... | | | | |/..... +---+---+---+---+...... ``` ## 说明/提示 NOIP2008 普及组第四题
最新发布
12-01
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值