hdu2604 递推转换矩阵快速幂

刚开始还以为用位运算与或几下几个循环就搞定了,算着算着发现不行........

还是一种固定的切题角度,我假设有长度为n,总的排列数位f(n),怎么算他呢?从后往前考虑,因为大多数情况,都是用前面的结果推后面的结果, 那么当第n位是m的时候,如果我知道f(n-1)等于多少,那么f(n-1)的排列+加一个m是不是就是f(n)的一部分解了?  对吧,以此类推,   当第n位为f的时候,可是fff,fmf不能连着 那是不是就剩下ffm,fmm的情况了,对于前者ffm,由于不能凑成ffmf的情况,所以只能是f(n-4). 对于后者fmm,无论邻接m的是什么都不会冲突,所以有f(n-3).至此全了,第n位的所有情况都考虑到了,那么就算出了以下公式:

f(n)=f(n-1)+f(n-3)+f(n-4)

写出代码拍上去发现超时了..........莫办法只能矩阵优化一下看看了.

我们设 有矩阵A  使  (f[n],f[n-1],f[n-2],f[n-3]) = (f[n-1],f[n-2],f[n-3],f[n-4])*A成立

求出A={{1,0,1,1},{1,0,0,0},{0,1,0,0},{0,0,1,0}}

所以有 (f[n],f[n-1],f[n-2],f[n-3])=(f[1],f[2],f[3],f[4])*A的n-4次幂

上代码

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4
 5 using namespace std;
 6
 7 int answer[5];
 8 struct mac
 9 {
10     int m[4][4];
11 };
12 mac power(mac x,mac y,int p)
13 {
14     mac temp;
15     for(int i=0;i<4;i++)
16     {
17         for(int j=0;j<4;j++)
18         {
19             temp.m[i][j]=0;
20             for(int k=0;k<4;k++)
21                 temp.m[i][j]=(temp.m[i][j]+x.m[i][k]*y.m[k][j])%p;
22         }
23     }
24     return temp;
25 }
26 void eachother(int n,int k)
27 {
28     mac pri,unit;
29     memset(unit.m,0,sizeof(unit.m));
30     memset(pri.m,0,sizeof(pri.m));
31     unit.m[0][0]=unit.m[1][1]=unit.m[2][2]=unit.m[3][3]=1;
32     pri.m[0][0]=pri.m[0][2]=pri.m[0][3]=pri.m[1][0]=pri.m[2][1]=pri.m[3][2]=1;
33     while(n)
34     {
35         if(n&1)
36         {
37             unit = power(unit,pri,k);
38         }
39         pri = power(pri,pri,k);
40         n >>= 1;
41     }
42     int ans = (answer[4]*unit.m[0][0]+answer[3]*unit.m[0][1]+answer[2]*unit.m[0][2]+answer[1]*unit.m[0][3])%k;
43     printf("%d\n",ans);
44 }
45 int main()
46 {
47     int n,k;
48     while(scanf("%d%d",&n,&k)!=EOF)
49     {
50         memset(answer,0,sizeof(answer));
51         answer[1]=2;
52         answer[2]=4;
53         answer[3]=6;
54         answer[4]=9;
55         if(n<=4)
56         {
57             printf("%d\n",answer[n]%k);
58         }
59         else{
60            eachother(n-4,k);
61         }
62     }
63     return 0;
64 }
时间: 2024-11-05 21:54:03

hdu2604 递推转换矩阵快速幂的相关文章

[HDOJ2604]Queuing(递推,矩阵快速幂)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2604 递推式是百度的,主要是练习一下如何使用矩阵快速幂优化. 递推式:f(n)=f(n-1)+f(n-3)+f(n-4),其中f(0)=2, f(1)=4, f(2)=6, f(3)=9. 当n>4时候,需要通过这个关系来递推. 构造矩阵这种东西我以前一直认为是很玄学的,但是如果深入研究的话不难发现其实也有规律可循.这是一个齐次递推式,很好构造. 我们希望通过如下矩阵(1)得到矩阵(2) | f(n

hihoCoder 1143 : 骨牌覆盖问题&#183;一(递推,矩阵快速幂)

[题目链接]:click here~~ 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 骨牌,一种古老的玩具.今天我们要研究的是骨牌的覆盖问题: 我们有一个2xN的长条形棋盘,然后用1x2的骨牌去覆盖整个棋盘.对于这个棋盘,一共有多少种不同的覆盖方法呢? 举个例子,对于长度为1到3的棋盘,我们有下面几种覆盖方式: 提示:骨牌覆盖 提示:如何快速计算结果 输入 第1行:1个整数N.表示棋盘长度.1≤N≤100,000,000 输出 第1行:1个整数,表示覆盖方案数 M

[题解][SHOI2013]超级跳马 动态规划/递推式/矩阵快速幂优化

这道题... 让我见识了纪中的强大 这道题是来纪中第二天(7.2)做的,这么晚写题解是因为 我去学矩阵乘法啦啦啦啦啦对矩阵乘法一窍不通的童鞋戳链接啦 层层递推会TLE,正解矩阵快速幂 首先题意就是给你一个 n 行m 列 的格子图 一只马从棋盘的左上角跳到右下角.每一步它向右跳奇数列,且跳到本行或相邻行. 题意很简单暴力dp的思路也很简单但是数据很恶心虽然远古一点,但毕竟是省选题 1 ≤ n ≤ 50,2 ≤ m ≤ 10^9 不过还是给了我们一点提示:n这么小? 总之我们先找出转移式对于每一个点

「常系数齐次线性递推」——矩阵快速幂的优化

引入: 对于递推方程: $$F(x) = \sum_{i=1}^k a_iF(x-i)$$ 我们显然会得到一个关于$F$的多项式求逆或者矩阵递推式,大多数情况下我们都是用后者,但是当$k$很大的时候,$k^3log n$的时间复杂度我们是吃不消的,那么自然我们的前人就搞出了一些优化. 特征多项式及Cayley-Hamilton定理: 一.特征多项式的定义: 设$A$是$n$阶矩阵,若数$\lambda$和非零列向量$x$使关系式$$Ax=\lambda x\;\;\;\;\;(1)$$ 成立,那

2016 pku campusH/OpenJ_POJ - C16H(推公式+矩阵快速幂)

传送门:http://poj.openjudge.cn/practice/C16H?lang=en_US 题面:描述 Wenwen has a magical ball. When put on an infinite plane, it will keep duplicating itself forever. Initially, Wenwen puts the ball on the location (x0, y0) of the plane. Then the ball starts

CCF 201312-4 有趣的数 (数位DP, 状压DP, 组合数学+暴力枚举, 推公式, 矩阵快速幂)

问题描述 我们把一个数称为有趣的,当且仅当: 1. 它的数字只包含0, 1, 2, 3,且这四个数字都出现过至少一次. 2. 所有的0都出现在所有的1之前,而所有的2都出现在所有的3之前. 3. 最高位数字不为0. 因此,符合我们定义的最小的有趣的数是2013.除此以外,4位的有趣的数还有两个:2031和2301. 请计算恰好有n位的有趣的数的个数.由于答案可能非常大,只需要输出答案除以1000000007的余数. 输入格式 输入只有一行,包括恰好一个正整数n (4 ≤ n ≤ 1000). 输

10.02 T3 打表找递推式+十进制快速幂 九校联考凉心模拟DAY1T1

题目背景 金企鹅同学非常擅长用1*2的多米诺骨牌覆盖棋盘的题.有一天,正 在背四六级单词的他忽然想:既然两个格子的积木叫“多米诺(domino)”,那 么三个格子的的积木一定叫“三米诺(tromino)”了!用三米诺覆盖棋盘的题 怎么做呢? 题目描述 用三米诺覆盖3n 的矩形棋盘,共多少种方案?三米诺可旋转:两种 方案不同当且仅当这两种图案直接覆盖在一起无法重叠. 输入输出格式 输入格式: 一行一个整数n(n<=10^40000),表示棋盘列数. 输出格式: 一行一个整数,表示方案数,对9982

ACM学习历程—SNNUOJ 1110 A Simple Problem(递推 &amp;&amp; 逆元 &amp;&amp; 组合数学 &amp;&amp; 快速幂)(2015陕西省大学生程序设计竞赛K题)

Description Assuming a finite – radius “ball” which is on an N dimension is cut with a “knife” of N-1 dimension. How many pieces will the “ball” be cut into most?However, it’s impossible to understand the following statement without any explanation.L

HDU 4686 (推公式+矩阵快速幂)

题目连接:传送门 题意: 给定ai,bi的推倒公式,求sigma(ai*bi) ( 0<= i < n) 分析: A0 = A0 Ai = Ai-1*Ax+Ay B0 = B0 Bi = Bi-1*Bx+By 设Fi表示Ai*Bi Fi = Ai * Bi ===>    Fi = (Ai-1*Ax + Ay)*(Bi-1*Bx + By) ===>    Fi = Ax*Bx*(Ai-1*Bi-1) + Ax*By*Ai-1 + Bx*Ay*Bi-1 ===>    Fi