题目描述
小可可参观科学博物馆时,看到一件藏品,上面有密密麻麻的数字,如下所示:
1 2 3 5 8 13 21 34 55 89 144 ...
4 7 11 18 29 47 76 123 199 322 521 ...
6 10 16 26 42 63 110 178 288 466 754 ...
9 15 24 39 63 102 165 267 432 699 1131 ...
12 20 32 52 84 136 220 356 576 932 1508 ...
14 23 37 60 97 157 254 411 665 1076 1741 ...
17 28 45 73 118 191 309 500 809 1309 2118 ...
19 31 50 81 131 212 343 555 898 1453 2351 ...
22 36 58 94 152 246 398 644 1042 1686 2728 ...
25 41 66 107 173 280 453 733 1186 1919 3105 ...
27 44 71 115 186 301 487 788 1275 2063 3338 ...
...
仔细一分析,发现还挺有规律。
原来,第一行是Fibonacci数列。即,该行中除了第一个和第二个数分别为1和2之外,其他数都是其左侧相邻的两个数之和。
其后各行也类似于Fibonacci数列。只是第i行的第一个数是前 行中未出现的最小正整数,而其第二个数与该行第一个数以及所在行的编号相关,即A[i,2]=A[i,1]*2-(i-1) 。如在第一行中未出现的最小正整数为4,前三行中未出现的最小正整数为9。故第二行以4和7开头,而第四行以9和15开头。
小可可高兴地把这个发现告诉了爷爷。爷爷问道:你能否一口报出第i行、第j列的那个数对m取模的结果是多少呢?
聪明的小可可通过心算就能知道答案。你是否能编写程序求解呢?
输入
每行有三个分别用一个空格隔开的正整数,分别是i、j和m。其中,i, j<=1000000000 ,2<=m<=10000 。
输出
每行输出对应的第i行、第j列的那个正整数对m取模的结果。
样例输入
1 2 99
样例输出
2
【分析】
这题贼强啊,想了好久还是没搞出来啊。最原始的想法显然是直接搞出第一项啊。显然是可以用暴力的。但是数据量太大了,数组肯定是开不了的。所以直接放弃了。然后就是找规律了。按照上面给的一个表,可以很明显的发现,如果只看首项的话,显然有每两行之间的差值是2或者3,然后我就写了一发暴力程序,弄出了前面两百项,however,虽然都是2和3,但是2,3出现的毫无规律,如果说有的话,可能就是3比2多(-_-!)。然后就没办法了,只有问大佬怎么搞得,终于学到了。说是什么斐波那契最小拆分。果然强啊。
首先,对于第i行来说,你用fibonacci数列里面的数来表示i-1,转换成二进制,然后在后面加上两个数0,1。然后对应到fibonacci里面去求和。就得到了首项。举个栗子:
对于第5行来说,你先弄出i-1,也就是4,4用fibonacci数列来表示就是101(也就是1+3),然后加上01,变成10101(也就是1+3+8=12),所以第五行第一列就是12。
虽然我也不知道为啥。
然后剩下的事就是矩阵快速幂的事了。轻松水过。
【代码】
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<vector>
#include<cmath>
#inc