第一题 hdu 1757 A Simple Math Problem
点击打开链接
思路:矩阵快速幂
分析:
1 最简单的矩阵快速幂的题目,直接利用矩阵求解即可
点击打开查看代码
第二题 hdu 1575Tr A
点击打开hdu 1575
思路: 矩阵快速幂
分析:
1 题目给定一个n*n的矩阵要求矩阵的k次幂之后的矩阵的对角线的和
2 矩阵快速幂的裸题
点击打开查看代码
第三题 hdu 2604 Queuing
点击打开hdu 2604
思路: 递推+矩阵快速幂
分析;
1 根据题目的意思,我们可以求出F[0] = 0 , F[1] = 2 , F[2] = 4 , F[3] = 6 , F[4] = 9 , F[5] = 15
2 那么根据上面前5项我们可以求出n >= 5的时候 F[n] = F[n-1]+F[n-3]+F[n-4]
那么我们就可以构造出矩阵
| 1 0 1 1 | | F[n-1] | | F[n] |
| 1 0 0 0 | * | F[n-2] | = | F[n-1] |
| 0 1 0 0 | | F[n-3] | | F[n-2] |
| 0 0 1 0 | | F[n-4] | | F[n-3] |
点击打开查看代码
第四题 hdu 2256Problem of Precision
点击打开hdu 2256
思路: 矩阵快速幂
分析:
1 题目要求的是(sqrt(2)+sqrt(3))^2n %1024向下取整的值
3 这里很多人会直接认为结果等于(an+bn*sqrt(6))%1024,但是这种结果是错的,因为这边涉及到了double,必然会有误差,所以根double有关的取模都是错误的思路
点击打开查看代码
第五题 codeforces 185APlant
点击打开cf 185A
思路: 递推+矩阵快速幂
分析:
1 题目要求找到在n年后向上三角形的个数
2 写出前面的几个数F(0) = 1 , F(1) = 3 , F(2) = 10 , F(3) = 36 , F(4) = 136
通过前面几项我们可以找到通项公式F[n] = 4*F[n-1]-2^(n-1)
那么我们通过够找矩阵
| 4 -1 | * | F(n-1) | = | F(n) |
| 0 2 | | 2^(n-1) | | 2^n |
3 那么够造出矩阵之后我们直接利用矩阵快速幂,由于矩阵开始有负数,所以应该在取模的时候注意一下
点击打开查看代码
第六题 hdu 2842Chinese Rings
点击打开hdu2842
思路: 矩阵快速幂
分析:
1 题目的意思是给定n个环,和一些规则要把所有的环全部拆下最少需要的步数
2 题目规定如果要拆第n个环,那么第n-1个要挂着,n-2环要被拆下。那么我们设f(n)表示拆下前n个环的最少的步骤
那么考虑第n个环的情况,第n-1个环必须要挂着,n-2环要拆下,那么这一步就要f(n-2),拆下第n个需要1步。然后只剩下第n-1个环,由于n-1环需要第n-2环挂着,所以我们需要把前n-2个环挂上去,所以需要f(n-2),剩下n-1个需要拆下需要f(n-1)。那么总的需要f(n) = f(n-2)+1+f(n-2)+f(n-1) => f(n) = 2*f(n)+f(n-1)+1
3 接下来利用矩阵快速幂即可
点击打开查看代码
第七题 hdu 2276Kiki & Little Kiki 2
点击打开hdu 2276
思路: 矩阵快速幂
分析:
1 题目给定一个01字符串然后进行m次的变换,变换的规则是:如果当前位置i的左边是1(题目说了是个圆,下标为0的左边是n-1),那么i就要改变状态0->1 , 1->0
比如当前的状态为100101那么一秒过后的状态为010111
2 假设0/1串的长度为n,保存在a数组,下标从0开始
根据上面的规则我们发现可以得出一秒过后的状态即为a[i] = (a[i]+a[i-1])%2 , 对于a[0] = (a[0]+a[n-1])%2
那么我们就可以就能够找到递推的式子
1 1 0 0.... a0 a1
0 1 1 0... * a1 = a2
..........1 1 ..... .....
1 0 0.....1 an-1 a0
3 但是我们最后要求的是a0 a1 .... an-1 , 所以我们应该把矩阵的第一行和最和一行调换一下,然后进行m次的快速幂即可
4 由于最后的结果是mod2的结果,因此我们可以把所有的*和+运算全部改成&和^
5 由于初始的矩阵是一个循环同构的矩阵,因此我们可以每次先求出第一行,然后在递推出第二行,那么这样就从O(n^3)降到O(n^2)
第八题 hdu 2254 奥运
点击打开hdu 2254
思路: 矩阵乘法
分析:
1 题目给定一个有向图,要求t1-t2天内v1-v2的路径的个数
2 假设有向图的邻接矩阵为A,那么A表示的是有向图中走一步能够到达哪些点的方案数,那么A^n表示的是走n步能够到达哪些点的方案数
3 根据离散数学里面的可达矩阵的性质,我们知道一个有向图的邻接矩阵的前n次幂的和即为可达矩阵,那么要求[t1-t2]之内的路径的条数,因为题目说了t1 = 0的时候为0。那么假设邻接矩阵为A,那么要求的就是A^(t1-1)+A^(t1)+...+A^(t2-1),为什么是从t1-1开始呢,因为邻接矩阵本身代表走一步的结果
3 还有点的范围很大,边数很少,所以我们应该要进行离散化
4 但是数据量很大,对于具体的一组我们应该要事先求出具体的每一个矩阵,然后直接使用即可
点击查看代码
第九题 hdu 3117Fibonacci Numbers
点击打开hdu 3117
思路: 矩阵快速幂
分析:
1 题目要求的是求F(n)中如果位数的个数大于8那么要输出前4四位和后四位,没有到8位的时候直接输出
2 根据题目的样例我们可以知道当n = 40的时候就超过8位了,所以我们可以知道n <= 39的时候直接去求F(n),超过40的时候我们就要去求前4位和后四位
3 我们利用矩阵快速幂可以很快的求出后四位,但是前面四位就很困难了
下面看一下网上的解法:转载自点击打开链接
点击查看代码
第十题 hdu 4686 Arc of Dream
点击打开hdu 4686
思路: 矩阵快速幂
分析:
1 题目给定一个式子求和,那么根据题目给定的,我们可以求出an*bn = (an-1*Ax+Ay)*(bn-1*Bx+By) => an-1*bn-1*Ax*Bx+an-1*Ax*By+bn-1*Ay*Bx+Ay*By
2 那么我们根据上面的等式可以推出矩阵的乘法
3 那么我们要求的是AoD(n)相当于求左边矩阵的n次幂,然后利用结果乘上初始值
4 注意特判n为0的时候,结果为0。然后注意初始的值
点击查看代码
第十一题 zoj 3690 Choosing number
点击打开zoj 3690
思路: 递推+矩阵快速幂
分析;
1 题目的意思是有n个人和m个数和一个k,现在每个人可以选择一个数,但是要求如果相邻的两个人选择相同的数,那么这个数要大于k
2 假设F(n)表示前n个人第n个人选择的数大于k的个数,G(n)表示的是前n个人第n个人选择的数小于等于k的个数
那么F(n) = F(n-1)*(m-k)+G(n-1)*(m-k) , G(n) = F(n-1)*k+G(n-1)*(k-1) , 那么最后的结果就是F(n)+G(n);
那么我们可以构造出矩阵
| m-k m-k| | F(n-1) | | F(n) |
| k k-1| * | G(n-1) | => | G(n) |
那么初始值F(1) = m-k , G(1) = k
点击查看代码
第十二题 FZU 1683 纪念SlingShot
点击打开FZU1683
思路: 矩阵快速幂
分析:
1 题目给定f(n) = 3*f(n-1)+2*f(n-2)+7*f(n-3) , f(0) = 1 , f(1) = 3 , f(2) = 5 ,给定n求f(0)+...+f(n) %2009
2 矩阵快速幂的水题,我们构造出这样的矩阵,然后利用矩阵快速幂即可
3 2 7 0 f(n-1) f(n)
1 0 0 0 * f(n-2) = f(n-1)
0 1 0 0 f(n-3) f(n-2)
3 2 7 1 sum sum'
点击查看代码
第十三题 hdu 3306 Another kind of Fibonacci
点击打开hdu 3306
思路: 矩阵快速幂
分析:
1 题目给定另外一种递推式,A(0) = 1 , A(1) = 1 , A(N) = X * A(N - 1) + Y * A(N - 2) (N >= 2).求 S(N) , S(N) = A(0)2 +A(1)2+……+A(n)2
2 那么我们通过这个式子就可以构造出以下的矩阵
点击查看代码
第十四题 UESTC 1335 Fibonacci
点击打开UESTC 1335
思路: 矩阵快速幂
分析:
1 最简单的矩阵快速幂
点击查看代码
第十五题 poj 3233 Matrix Power Series
点击打开poj 3233
思路: 二分求和+矩阵快速幂
分析:
1 题目给定一个n*n的矩阵A,要求(A+A^2+....A^K)%m后的矩阵
2 对于任意的A^x,我们都能够利用矩阵快速幂求出,但是我们现在要求的是和。
仔细观察整个式子,那么我们可以对原式进行变形
如果k为偶数,那么(A+A^2+....A^K) = (A+...+A^K/2)+A^K/2*(A+...+A^K/2)
如果k为奇数,那么(A+A^2+....A^K) = (A+...+A^K/2)+A^K/2*(A+...+A^K/2)+A^k
3 那么对于上面的式子的变形,就是二分的思想,那么我们可以利用二分来求和,然后对于单个的矩阵的x次方我们利用快速幂
点击查看代码第十六题 hdu 4565 So Easy!
点击打开hdu 4565
思路: 递推+矩阵快速幂
分析:
1 这一题和hdu 2256
几乎就是一模一样的题目,只是这边要求的是向上取整
那么我们按照hdu2256的思路来做即可点击打开hdu 2256
点击查看代码
第十七题 uva 10870 Recurrences
点击打开uva 10870
思路:构造矩阵+矩阵快速幂
分析:
1 题目给定f(n)的表达式 f(n) = a1 f(n - 1) + a2 f(n - 2) + a3 f(n -3) + ... + ad f(n - d)对于n > d的时候
2 那么我们可以构造出矩阵
a1 a2 ... an f(n-1) f(n)
1 0 ......... 0 f(n-2) f(n-1)
0 1 ..........0 * ........ => ......
.................. ....... ......
0 0 ...... 1 0 ....... f(n-d)
0 0 0 0 ... 0 f(n-d) f(n-d+1)
3 题目有个地方错了,两个case之间根本不需要空行
点击查看代码
第十八题 light oj 1132 Summing up Powers
点击打开light oj 1132
思路: 构造矩阵+矩阵快速幂
分析:
1 题目给定n和k要求(1K + 2K + 3K+ ... + NK) % 232
2 具体的思路见下图
3 对于求组合数,我们可以利用公式C(n , k+1) = C(n , k)*(n-k)/(k+1) ,那么我们可以先打表求出50之内的所有的组合数
点击查看代码第十九题 FZU 1692 Key problem
点击打开FZU 1692
思路: 构造矩阵+矩阵快速幂
分析:
1 题目的意思是有n个人构成一个圈,每个人初始的有ai个苹果,现在做m次的游戏,每一次游戏过后第i个人能够增加R*A(i+n-1)%n+L*A(i+1)%n 个苹果(题目有错),问m轮游戏过后每个人的苹果数
2 根据题目的意思我们能够列出一轮过后每个人的苹果数
a0 = a0+R*an-1+L*a1
a1 = a1+R*a0+L*a2
.............................
an-1 = an-1+R*an-2+L*a0
3 根据第二条思路我们可以构造出如下的矩阵
1 L 0 ...... R a0 a0'
R 1 L ......... * a1 a1'
................... .... = ......
...........R 1 L an-2 an-2'
L ...........R 1 an-1 an-1'
4 那么根据3我们可以利用矩阵快速幂求出最后的答案,但是题目的n最大为100,m最大为10^9,那么每个case的时间复杂度为O(Logm*n^3),当n最大为100的时候是会TLE的
5 我们发现初始的矩阵里面,矩阵是一个循环同构的,就是说矩阵的每一行度能够从上一行推出,那么我们只要利用O(n^2)的时间求出第一行,然后我们在利用递推求出剩下的n-1行,那么总的时间复杂度为O(Logm*n^2)
点击查看代码
第二十题 hdu 4291 A Short problem
点击打开hdu 4291
思路: 循环节+矩阵快速幂
分析:
1 题目给定g(n) = 3*g(n-1)+g(n-2) , g(1) = 1 , g(0) = 0 , 要求g(g(g(n)))%10^9+7
2 最初的想法是从里面一层一层的求出g(n),每一次都利用矩阵快速幂。但是发现嵌套的时候只有最外层是%(10^9+7),但是里面两层如果%(10^9+7)的话答案是错的。
那么这里涉及到了循环节,最外层%(10^9+7),肯定有个循环节L1。那么我们可以通过求出的L1找到第二层的循环节为L2,通过第二层的循环节L2找到第三层的循环节L3
3 找循环节我们利用暴力求出即可。然后我们回答最初的思路上,只要做三次的矩阵快速幂,然后把相应要mod上相应的值即可
点击查看代码第二十一题 uva12470 Tribonacci
点击打开uva12470
思路: 矩阵快速幂
分析:
1 裸题
点击查看代码
第二十二题 hdu 2855 Fibonacci Check-up
点击打开hdu 2855
思路: 递推+矩阵快速幂
分析:
1 题目的意思是给定n和m,要求
2 这一题有两种思路,对于这种的题肯定是有递推式的,那么找不到递推式的时候我们尝试去打表
下面我打出了前几十项,发现了n >= 2的时候有f(n) = 3*f(n-1)-f(n-2),那么我们可以利用矩阵快速幂求f(n)
3 另一种思路是考虑f(n) = f(n-1) + f(n-2),那么我们可以利用矩阵求出任意的f(n)
1 1 * f(n-1) = f(n)
1 0 f(n-2) f(n-1)
那么对于n >= 2的时候,我们假设左边的矩阵为A,那么A^(n-1)即可求出答案
那么A^(n-1)为 f(n) f(n-1)
f(n-1) f(n-2)
那么根据我们知道二项式定理为(a+b)^n=C(n,0)a^n+C(n,1)a^(n-1)*b+C(n,2)a^(n-2)*b^2+...+C(n,n)b^n
那么我们发现所求的式子和上面很像,因为f(n)可以利用上面的A矩阵的n-1次方求出
那么原式所求变成(1+A)^n,这里的1为单位矩阵。因为做了n次方,那么最终的答案就是ans.mat[0][1] 或ans.mat[1][0]
点击查看代码第二十三题 hdu 3658How many words
点击打开hdu 3658
思路: 递推+矩阵快速幂
分析:
1 题目的意思是在52个英文字母里面选择m个字母组成一个字符串,满足以下两个条件。第一是相邻的两个字符的ASCLL码的绝对值小于等于32,第二至少要有一对的字符的绝对值为32
2 那么不考虑第二个条件的时候,我们可以求出所有的符合的个数。假设f(n)(j)表示的是前n个字符最后一个字符为j,那么我们可以求出所有满足第一个条件的所有个数。因为至少需要有一对相邻的字符的绝对值为32,那么我们只要把第一次求出的所有的个数减去“相邻的两个字符的ASCLL码的绝对值小于等于31”的即可
3 那么我们考虑“相邻的两个字符的ASCLL码的绝对值小于等于32”这种情况,f(n)(j) =Σ(f(n-1)(k)) , abs(j-k) <= 32
那么我们可以构造出如下的矩阵
4 那么相邻的两个字符的ASCLL码的绝对值小于等于31就和上面的类似
点击查看代码第二十四题 poj 3150Cellular Automaton
点击打开poj 3150
思路: 矩阵快速幂
分析:
1 题目给定n个数每个数在0~m-1之内,题目规定两个数之间的距离为min(|i-j| , n-|i-j|)。现在给定d和k,表示做k次的变换,每一次变换过后每个数变成了一个新的数。这个新的数等于和它距离小于等于d的所有数的和%m
2 这题和之前做的两道题很像hdu2276 和 FZU1692,都是属于循环同构的问题
那么我们先来看一下每个数在做一次变换过后变成什么。因为要距离小于等于d,第一种|i-j| = d , 则j = i+d , 第二种情况n-|i-j| = d , 因此 j = n-d+i 。
第一个数等于 = num[1]+num[2]+....+num[d+1]+num[n-d+1]+...+num[n]
第二个数等于 = num[2]+....+num[d+2]+num[n-d+2]+...+num[n]
..............................................................................................................
3 因为这里的矩阵是循环同构的,因此我们只要求出第一行,剩下的我们就可以根据前一行推出。这样就把矩阵的乘法的复杂度降到了O(n^2)
点击查看代码
第二十五题 poj 3735Training little cats
点击打开poj 3735
思路: 矩阵快速幂
分析:
1 题目给定n只猫,每只猫的初始的花生的数量为0。现在有三种操作,g i 第i只猫加一个花生,e i 把第i只猫的所有花生全部吃完 s i j 把第i 和 j只猫的花生数进行交换
2 根据上面的三种操作那么我们能够举例n = 3的时候的三种操作。
对于g 1,我们把第一行的最后一位加1,这里增加了一列目的是为了能够求出和,因为初始化a b c都为0
1 0 0 1 a a+1
0 1 0 0 * b = b
0 0 1 0 c c
0 0 0 1 1 1
对于e 1,我们把第一行全部置为0,那么这样就是相当于吃掉全部的花生
0 0 0 0 a 0
0 1 0 0 * b = b
0 0 1 0 c c
0 0 0 1 1 1
对于 s 1 2
0 1 0 0 a b
1 0 0 0 * b = a
0 0 1 0 c c
0 0 0 1 1 1
3 那么我们只要先把k次的操作整合到一个矩阵A里面,然后求A^m,矩阵的最后一列的前n个数即为所求
4 由于矩阵乘法涉及到乘的次数越多,就越耗时间,因此我们需要在矩阵相乘的时候进行优化
点击查看代码