矩阵快速幂(HDU-1757&&HDU-2604)

A Simple Math Problem HDU-1757

Lele now is thinking about a simple function f(x).

If x < 10 f(x) = x. 
If x >= 10 f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + …… + a9 * f(x-10); 
And ai(0<=i<=9) can only be 0 or 1 .

Now, I will give a0 ~ a9 and two positive integers k and m ,and could you help Lele to caculate f(k)%m.

InputThe problem contains mutiple test cases.Please process to the end of file. 
In each case, there will be two lines. 
In the first line , there are two positive integers k and m. ( k<2*10^9 , m < 10^5 )
In the second line , there are ten integers represent a0 ~ a9. 
Output

For each case, output f(k) % m in one line.

Sample Input

10 9999
1 1 1 1 1 1 1 1 1 1
20 500
1 0 1 0 1 0 1 0 1 0

Sample Output

45
104

矩阵快速幂的关键是由F(n-1)、F(n-2)、F(n-3).....怎么得到F(n)、F(n-1)、F(n-2).....此题将F(n-1)、F(n-2)、F(n-3).....看成矩阵A,它们的系数看成矩阵B,因为F(n)=a0 * F(n-1) + a1 * F(n-2) + a2 * F(n-3) + …… + a9 * F(n-10),所以B矩阵第一行填a0、a1、a2.....a9。 第二行由F(n-1)、F(n-2)、F(n-3).....得到F(n-1),所以第二行填1 0 0 0.....以此类推,矩阵如下图所示:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 typedef long long ll;
 6 ll k,mod;
 7 struct node{
 8     int m[15][15];
 9 }a,b;
10 void init()
11 {
12     memset(a.m,0,sizeof(a.m));
13     memset(b.m,0,sizeof(b.m));
14     for(int i=1;i<10;i++)
15     {
16         a.m[i][i-1]=1;
17     }
18     for(int i=0;i<10;i++)
19     {
20         b.m[i][i]=1;
21     }
22 }
23 node mul(node aa,node bb)
24 {
25     node c;
26     for(int i=0;i<10;i++)
27     {
28         for(int j=0;j<10;j++)
29         {
30             c.m[i][j]=0;
31             for(int k=0;k<10;k++)
32             {
33                 c.m[i][j]+=(aa.m[i][k]*bb.m[k][j])%mod;
34             }
35             c.m[i][j]%=mod;
36         }
37     }
38     return c;
39 }
40 node pow_mod(node aa,node bb,int t)
41 {
42     while(t)
43     {
44         if(t&1)
45         {
46             bb=mul(aa,bb);
47         }
48         aa=mul(aa,aa);
49         t>>=1;
50     }
51 return bb;
52 }
53 int main()
54 {
55     while(~scanf("%lld%lld",&k,&mod))
56     {
57         init();
58         for(int i=0;i<10;i++)
59         {
60             scanf("%d",&a.m[0][i]);
61         }
62         if(k<=9)
63         {
64             printf("%d\n",k%mod);
65             continue;
66         }
67         else
68         {
69             node res=pow_mod(a,b,k-9);
70             ll ans=0;
71             for(int i=0;i<10;i++)
72             {
73                 ans+=res.m[0][i]*(9-i)%mod;
74             }
75             printf("%lld\n",ans%mod);
76         }
77     }
78 }
79  

心得:一般矩阵快速幂的题求某个矩阵的多少次幂是看该矩阵从第几项开始满足矩阵快速幂乘法的。比如这个题前九项并不满足矩阵乘法,所以pow_mod里面的幂项是k-9(一般是前多少项不满足就减几)。

而pow_mod函数返回的值为矩阵乘完后的值,保存在res.m[0][i]中,最后ans为res.m[0][i]与前多少项不满足矩阵乘法的项的值的乘积。

Queuing  HDU-2604

Queues and Priority Queues are data structures which are known to most computer scientists. The Queue occurs often in our daily life. There are many people lined up at the lunch time. 

  Now we define that ‘f’ is short for female and ‘m’ is short for male. If the queue’s length is L, then there are 2 L numbers of queues. For example, if L = 2, then they are ff, mm, fm, mf . If there exists a subqueue as fmf or fff, we call it O-queue else it is a E-queue. 
Your task is to calculate the number of E-queues mod M with length L by writing a program.

InputInput a length L (0 <= L <= 10 6) and M.OutputOutput K mod M(1 <= M <= 30) where K is the number of E-queues with length L.Sample Input

3 8
4 7
4 8

Sample Output

6
2
1

本题的关键是推出f(n)=f(n-1)+f(n-3)+f(n-4)

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 using namespace std;
  5 typedef long long ll;
  6 ll l,mod;
  7 struct node{
  8     int m[15][15];
  9 }a,b;
 10 void init()
 11 {
 12     memset(a.m,0,sizeof(a.m));
 13     for(int i=0;i<4;i++)
 14     {
 15         if(i!=1)
 16             a.m[0][i]=1;
 17     }
 18     for(int i=1;i<4;i++)
 19     {
 20         a.m[i][i-1]=1;
 21     }
 22     memset(b.m,0,sizeof(b.m));
 23     for(int i=0;i<4;i++)
 24     {
 25         b.m[i][i]=1;
 26     }
 27 }
 28 node mul(node aa,node bb)
 29 {
 30     node c;
 31     for(int i=0;i<4;i++)
 32     {
 33         for(int j=0;j<4;j++)
 34         {
 35             c.m[i][j]=0;
 36             for(int k=0;k<4;k++)
 37             {
 38                 c.m[i][j]+=(aa.m[i][k]*bb.m[k][j])%mod;
 39             }
 40             c.m[i][j]%=mod;
 41         }
 42     }
 43 return c;
 44 }
 45 node pow_mod(node aa,node bb,int x)
 46 {
 47     while(x)
 48     {
 49         if(x&1)
 50         {
 51             bb=mul(aa,bb);
 52         }
 53         aa=mul(aa,aa);
 54         x>>=1;
 55     }
 56 return bb;
 57 }
 58 int f[4]={2,4,6,9};
 59 int main()
 60 {
 61     while(~scanf("%lld%lld",&l,&mod))
 62     {
 63         init();
 64         if(l<=4)
 65         {
 66             if(l==0)
 67             {
 68                 printf("0\n");
 69                 continue;
 70             }
 71             if(l==1)
 72             {
 73                 printf("%lld\n",2%mod);
 74                 continue;
 75             }
 76             if(l==2)
 77             {
 78                 printf("%lld\n",4%mod);
 79                 continue;
 80             }
 81             if(l==3)
 82             {
 83                 printf("%lld\n",6%mod);
 84                 continue;
 85             }
 86             if(l==4)
 87             {
 88                 printf("%lld\n",9%mod);
 89                 continue;
 90             }
 91         }
 92     node res=pow_mod(a,b,l-4);
 93         int ans=0;
 94       for(int i=0;i<4;i++)
 95       {
 96           ans+=f[3-i]*res.m[0][i]%mod;
 97       }
 98       printf("%lld\n",ans%mod);
 99     }
100 }

原文地址:https://www.cnblogs.com/1013star/p/9508323.html

时间: 2024-08-30 06:55:08

矩阵快速幂(HDU-1757&&HDU-2604)的相关文章

矩阵快速幂AC代码HDU 2035

#include <iostream> using namespace std;const int MOD = 1000;//像这样的一个常量就应该专门定义一下 int PowMod(int a, int n)//a^n%MOD { int ret = 1; while(n) { if(n & 1) ret = ret * a % MOD; //变为二进制,然后就可以专门进行分解计算,十分的方便,要求是结合位运算一同使用 a = a * a % MOD; //这里要求特别的注意,因为是

一些特殊的矩阵快速幂 hdu5950 hdu3369 hdu 3483

思想启发来自, 罗博士的根据递推公式构造系数矩阵用于快速幂 对于矩阵乘法和矩阵快速幂就不多重复了,网上很多博客都有讲解.主要来学习一下系数矩阵的构造 一开始,最一般的矩阵快速幂,要斐波那契数列Fn=Fn-1+Fn-2的第n项,想必都知道可以构造矩阵来转移 其中,前面那个矩阵就叫做系数矩阵(我比较喜欢叫转移矩阵) POJ3070 Fibonacci 可以试一试 1 #include<cstdio> 2 typedef long long ll; 3 const ll md=10000; 4 st

hdu 1757 A Simple Math Problem 矩阵快速幂

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1757 Lele now is thinking about a simple function f(x).If x < 10 f(x) = x.If x >= 10 f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + …… + a9 * f(x-10);And ai(0<=i<=9) can only be 0 or 1 .Now, I w

hdu 2604 Queuing dp找规律 然后矩阵快速幂。坑!!

http://acm.hdu.edu.cn/showproblem.php?pid=2604 这题居然O(9 * L)的dp过不了,TLE,  更重要的是找出规律后,O(n)递推也过不了,TLE,一定要矩阵快速幂.然后立马GG. 用2代表m,1代表f.设dp[i][j][k]表示,在第i位,上一位站了的人是j,这一位站的人是k,的合法情况. 递推过去就是,如果j是1,k是2,那么这一位就只能放一个2,这个时猴dp[i][k][2] += dp[i - 1][j][k]; 其他情况分类下就好,然后

HDU 2604 Queuing (矩阵快速幂)

HDU 2604 Queuing (矩阵快速幂) ACM 题目地址:HDU 2604 Queuing 题意: n个人排队,f表示女,m表示男,包含子串'fmf'和'fff'的序列为O队列,否则为E队列,有多少个序列为E队列. 分析: 矩阵快速幂入门题. 下面引用巨巨解释: 用f(n)表示n个人满足条件的结果,那么如果最后一个人是m的话,那么前n-1个满足条件即可,就是f(n-1): 如果最后一个是f那么这个还无法推出结果,那么往前再考虑一位:那么后三位可能是:mmf, fmf, mff, fff

HDU 1575 &amp;&amp; 1757 矩阵快速幂&amp;&amp;构造矩阵入门

HDU 1575 Tr A Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2912    Accepted Submission(s): 2167 Problem Description A为一个方阵,则Tr A表示A的迹(就是主对角线上各项的和),现要求Tr(A^k)%9973. Input 数据的第一行是一个T,表示有T组数据.每组

hdu 1757 (矩阵快速幂) 一个简单的问题 一个简单的开始

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1757 题意不难理解,当x小于10的时候,数列f(x)=x,当x大于等于10的时候f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + …… + a9 * f(x-10); 所求的是f(x)取m的模,而x,m,a[0]至a[9]都是输入项 初拿到这道题,最开始想的一般是暴力枚举,通过for循环求出f(x)然后再取模,但是有两个问题,首先f(x)可能特别大,其

HDU 2604 Queuing,矩阵快速幂

题目地址:HDU 2604 Queuing 题意: 略 分析: 易推出:   f(n)=f(n-1)+f(n-3)+f(n-4) 构造一个矩阵: 然后直接上板子: /* f[i] = f[i-1] + f[i-3] + f[i-4] */ #include<cstdio> #include<cstring> using namespace std; const int N = 4; int L, M; struct mtx { int x[N+1][N+1]; mtx(){ mem

hdu 2604 递推 矩阵快速幂

HDU 2604 Queuing (递推+矩阵快速幂) 这位作者讲的不错,可以看看他的 #include <cstdio> #include <iostream> #include <algorithm> #include <cmath> #include <cstring> using namespace std; const int N = 5; int msize, Mod; struct Mat { int mat[N][N]; }; M

hdu 2604 Queuing(矩阵快速幂乘法)

Problem Description Queues and Priority Queues are data structures which are known to most computer scientists. The Queue occurs often in our daily life. There are many people lined up at the lunch time. Now we define that ‘f’ is short for female and