cogs1493 递推关系 矩阵

继续填坑……链接:http://cogs.pro/cogs/problem/problem.php?pid=1493

题意:给出一个递推式:$f(n)=a[1]*f(n-1)+a[2]*f(n-2)+a[3]*f(n-3)+...+a[d]*f(n-d)$,求$f(n)$。

明显的矩阵推法……但是对于矩阵并不是很熟悉,所以自己打一发……

矩阵大概就是这个样子:

(公式炸了……)

然后快速幂就好了……

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 using namespace std;
 6 int mod,d,n;
 7 struct matrix
 8 {
 9     long long a[20][20];
10     matrix(){memset(a,0,sizeof(a));}
11     matrix operator *(const matrix &b)const
12     {
13         matrix c;
14         for(int i=1;i<=15;i++)
15             for(int j=1;j<=15;j++)
16                 for(int k=1;k<=15;k++)c.a[i][j]=(c.a[i][j]+a[i][k]*b.a[k][j])%mod;
17         return c;
18     }
19 };
20 matrix qpow(matrix x,int tim)
21 {
22     matrix c=x,tmp;
23     for(int i=1;i<=15;i++)tmp.a[i][i]=1;
24     for(;tim;tim>>=1,c=c*c)
25         if(tim&1)tmp=tmp*c;
26     return tmp;
27 }
28 int haha()
29 {
30     freopen("recurrences.in","r",stdin);
31     freopen("recurrences.out","w",stdout);
32     while(scanf("%d%d%d",&d,&n,&mod)!=EOF&&d&&&n&&mod)
33     {
34         matrix a,b;
35         for(int i=1;i<=d;i++)scanf("%d",&a.a[1][i]);
36         for(int i=2;i<=d;i++)a.a[i][i-1]=1;
37         for(int i=1;i<=d;i++)scanf("%d",&b.a[d-i+1][1]);
38         if(n<=d)
39         {
40             printf("%d\n",b.a[d-n+1][1]);
41             continue;
42         }
43         printf("%d\n",(qpow(a,n-d)*b).a[1][1]);
44     }
45 }
46 int sb=haha();
47 int main(){;}

cogs1493

时间: 2024-12-07 19:42:55

cogs1493 递推关系 矩阵的相关文章

Holiday 9

上午看了没多久矩阵就不想看了,准备无脑的码Splay,可是当我看着屏幕眼睛都难以长时间聚焦的的时候,心里蛮失落的.下午就突然看开了,没必要去强求什么,人生就是一场经历么.屌丝,能遇见女神就是莫大的幸福了.端正心态,尽力而为,别跟自己过不去,想玩就玩吧. COGS1493 递推关系 (http://218.28.19.228:8080/cogs/problem/problem.php?pid=1493) 今天早上还码了道矩阵快速幂累. 感谢每一天. 原文地址:https://www.cnblogs

递推关系转矩阵快速幂

一些递推关系如f(n) = af(n-1)+bf(n-2)+...+tf(n-k)等,在n很大的时候,O(n)的算法都不能满足要求的时候,往往可以化为矩阵快速幂来做,复杂度可以降为O(logn),大大减少了运行时间. 如何将一个递推关系式化为矩阵呢? 比如这样一个递推关系: f(n) = 2*f(n-1)+4*f(n-2) 先列出几个等式: f(n) = 2*f(n-1)+4*f(n-2) f(n-1) = 2*f(n-2)+4*f(n-3) 然后就有: 就可以将左边矩阵做n-2次幂,再乘初值,

hdu 4686 矩阵乘法优化递推关系

这里有一份解题报告 解题报告 这是理论知识: 点我 最主要的是构造乘法矩阵,这个是通过递推关系得到的. 有了它,求数列的第n项可以在log(n)的时间里求出来. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <set> 5 #include <algorithm> 6 #include <map> 7 #include<vect

2017中国大学生程序设计竞赛 - 网络选拔赛 HDU 6155 Subsequence Count 矩阵快速幂

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6155 题意: 题解来自:http://www.cnblogs.com/iRedBean/p/7398272.html 先考虑dp求01串的不同子序列的个数. dp[i][j]表示用前i个字符组成的以j为结尾的01串个数. 如果第i个字符为0,则dp[i][0] = dp[i-1][1] + dp[i-1][0] + 1,dp[i][1] = dp[i-1][1] 如果第i个字符为1,则dp[i][1

hdu 5015 233 Matrix (矩阵高速幂)

233 Matrix Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 749    Accepted Submission(s): 453 Problem Description In our daily life we often use 233 to express our feelings. Actually, we may s

[矩阵快速幂+循环节]hdu4291

题意: Given n (1 <= n <= 1018), You should solve for g(g(g(n))) mod 109 + 7 where g(n) = 3g(n - 1) + g(n - 2) g(1) = 1 g(0) = 0 分析: 这个递推关系可以用矩阵快速幂来解决,但是这个题的问题是mod很大,会爆long long 并且超时的.那么这就需要一些特技了. 于是看到大家都用的循环节,但是网上对为什么要这么取循环节却都模糊或者答非所问,大概都不太晓得,知道可以A提就可

矩阵构造

[转]http://www.cnblogs.com/frog112111/archive/2013/05/19/3087648.html 讲得不是一般的好: Fibonacci数列:F(0)=Fibonacci数列:F(0)=1 , F(1)=1 , F(n)=F(n-1)+F(n-2) 我们以前快速求Fibonacci数列第n项的方法是 构造常系数矩阵 (一)   Fibonacci数列f[n]=f[n-1]+f[n-2],f[1]=f[2]=1的第n项快速求法(不考虑高精度) 解法: 考虑1

矩阵乘法递推的优化艺术

对于一个线性递推式,求它第项的值,通常的做法是先构造一个的矩阵,然后在时间内求出. 其实,由于这个矩阵的特殊性,可以将时间优化到.接下来我会以一个题目来讲解矩阵乘法递推的优化. 题目:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1229 题意:设,求的值.其中,和 . 前言:本题如果用普通的矩阵做法,很明显会TLE.那么我们要对这个特殊的矩阵进行时间上的优化. 分析:本题主要可用两种方法解决,分别是错位相减和矩阵乘法

HDU 2604 矩阵快速幂

题目大意 给定长度为l的只有f,m两种字母 的序列,问不出现fff,fmf的序列个数有多少个 每次的下一个状态都与前一次状态的后两个字母有关 比如我令mm : 0 , mf : 1 , fm : 2 , ff : 3: 那么dp[i][j] 表示长度为i的序列最后由j状态结尾的总个数,当然 j 要大于2 dp[i][0] = dp[i-1][0] + dp[i-1][2] dp[i][1] = dp[i-1][0] dp[i][2] = dp[i-1][1] + dp[i-1][3] dp[i]