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

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组数据。
每组数据的第一行有n(2 <= n <= 10)和k(2 <= k < 10^9)两个数据。接下来有n行,每行有n个数据,每个数据的范围是[0,9],表示方阵A的内容。

Output

对应每组数据,输出Tr(A^k)%9973。

Sample Input

2

2 2

1 0

0 1

3 99999999

1 2 3

4 5 6

7 8 9

Sample Output

2

2686

一个矩阵快速幂搞定。。



 1 #include <cstdio>
 2 #include <iostream>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <vector>
 6 #include <queue>
 7 using namespace std;
 8 #define MOD 9973
 9 typedef __int64 LL;
10
11 struct node{
12     LL g[11][11];
13 };
14
15 int n, m;
16
17 node cheng(node a,node b){
18     node c;
19     int i, j, k;
20
21     memset(c.g,0,sizeof(c.g));
22     for(i=0;i<n;i++){
23         for(k=0;k<n;k++){
24             if(!a.g[i][k]) continue;
25             for(j=0;j<n;j++)
26             c.g[i][j]=(c.g[i][j]+a.g[i][k]*b.g[k][j])%MOD;
27         }
28     }
29
30     return c;
31 }
32
33 node pow(node a,int mm){
34     node ans;
35     int i, j;
36     memset(ans.g,0,sizeof(ans.g));
37     for(i=0;i<n;i++) ans.g[i][i]=1;
38     while(mm){
39         if(mm&1) ans=cheng(ans,a);
40         a=cheng(a,a);
41 mm>>=1;
42     //    cout<<mm<<endl;
43     }
44
45     return ans;
46 }
47
48 main()
49 {
50     int t, i, j, k;
51     cin>>t;
52     while(t--){
53         node a;
54         scanf("%d %d",&n,&m);
55         for(i=0;i<n;i++){
56             for(j=0;j<n;j++)
57             scanf("%I64d",&a.g[i][j]);
58         }
59
60         a=pow(a,m);
61
62         LL ans=0;
63         for(i=0;i<n;i++){
64             ans=(ans+a.g[i][i])%MOD;
65         }
66         printf("%I64d\n",ans);
67     }
68 }

HDU 1757

A Simple Math Problem

Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2751    Accepted Submission(s): 1628

Problem Description

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.

Input

The 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[x]怎么得到,然后求f[k]%m。

思路:

这道题可以找通项公式来算,但是比较麻烦,而这道题很明显可以用矩阵相乘来算。

已知  当x<10  ,f[x]=x;

所以咱们可以由以下矩阵相乘算以后的项 ,如下:

|                |   |f[0]|    |f[1]|

|                |   |f[1]|    |f[2]|

|                |   |f[2]|    |f[3]|

|                |   |f[3]|    |f[4]|

|                | * |f[4]| =  |f[5]|

|                |   |f[5]|    |f[6]|

|                |   |f[6]|    |f[7]|

|                |   |f[7]|    |f[8]|

|                |   |f[8]|    |f[9]|

|                |   |f[9]|    |f[10]|

(构造的矩阵a)     (矩阵b)  (矩阵c)

当x<10的时候直接输出即可,当x>10  ,a^(x-9)*b就可以得到f[x]了。

而a^(x-9)用矩阵快速幂可以快速算出,时间复杂度为O(logn)。

很容易得出构造的矩阵a为:

0,1,0,0,0,0,0,0,0,0

0,0,1,0,0,0,0,0,0,0

0,0,0,1,0,0,0,0,0,0

0,0,0,0,1,0,0,0,0,0

0,0,0,0,0,1,0,0,0,0

0,0,0,0,0,0,1,0,0,0

0,0,0,0,0,0,0,1,0,0

0,0,0,0,0,0,0,0,1,0

0,0,0,0,0,0,0,0,0,1

a9,a8,a7,a6,a5,a4,a3,a2,a1,a0

代码如下:

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <vector>
 6 #include <queue>
 7 using namespace std;
 8
 9 typedef __int64 LL;
10 int n;
11 LL MOD;
12
13 struct node{
14     LL g[10][10];
15 };
16 int a[10];
17
18 node init(){
19     node c;
20     int i;
21     memset(c.g,0,sizeof(c.g));
22     for(i=0;i<9;i++) c.g[i][i+1]=1;
23     for(i=0;i<10;i++) c.g[9][i]=a[9-i];
24
25
26     return c;
27 }
28
29 node cheng(node A,node B){
30     node C;
31     memset(C.g,0,sizeof(C.g));
32     int i, j, k;
33     for(i=0;i<10;i++){              //这里有个小技巧,把原本俩矩阵相乘的代码中j和k的位置换一下 ,很明显的提高了时间效率
34         for(k=0;k<10;k++){
35             if(!A.g[i][k]) continue;
36             for(j=0;j<10;j++)
37             C.g[i][j]=(C.g[i][j]+A.g[i][k]*B.g[k][j])%MOD;
38         }
39     }
40     return C;
41 }
42
43 node pow(node c,int mm){
44     node A;
45     int i;
46     memset(A.g,0,sizeof(A.g));
47     for(i=0;i<10;i++) A.g[i][i]=1;
48     while(mm){
49         if(mm&1) A=cheng(A,c);
50         c=cheng(c,c);
51         mm>>=1;
52     }
53     return A;
54 }
55
56 main()
57 {
58     int i, j, k;
59     __int64 f[]={0,1,2,3,4,5,6,7,8,9};
60
61     while(scanf("%d %I64d",&n,&MOD)==2){
62         for(i=0;i<10;i++) scanf("%d",&a[i]);
63         if(n<10) {printf("%I64d\n",f[n]);continue;}
64         node c=init();  //构造矩阵
65
66
67         n=n-9;
68         c=pow(c,n);    //矩阵快速幂优化矩阵相乘
69         LL ans=0;
70         for(i=0;i<10;i++)
71         ans=(ans+c.g[9][i]*f[i])%MOD;
72         printf("%I64d\n",ans);
73
74     }
75 }
时间: 2024-10-12 19:15:09

HDU 1575 && 1757 矩阵快速幂&&构造矩阵入门的相关文章

FZU 1911 Construct a Matrix ( 矩阵快速幂 + 构造 )

FZU 1911 Construct a Matrix (  矩阵快速幂 + 构造 ) 题意: 需要构造一个矩阵满足如下要求: 1.矩阵是一个S(N)*S(N)的方阵 2.S(N)代表斐波那契数列的前N项和模上M 3.矩阵只能由1, 0, -1组成 4.矩阵每行每列的和不能相等 Here, the Fibonacci numbers are the numbers in the following sequence: 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 1

LA 3704 (矩阵快速幂 循环矩阵) Cellular Automaton

将这n个格子看做一个向量,每次操作都是一次线性组合,即vn+1 = Avn,所求答案为Akv0 A是一个n*n的矩阵,比如当n=5,d=1的时候: 不难发现,A是个循环矩阵,也就是将某一行所有元素统一向右移动一位便得到下一行. 而且循环矩阵相乘仍然是循环矩阵,所以只要求出Ak的第一行就行了. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 6

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

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 2604

对应HDU题目:点击打开链接 Queuing Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3114    Accepted Submission(s): 1419 Problem Description Queues and Priority Queues are data structures which are known t

HDU 2604 Queuing (递推+矩阵快速幂)

[题目链接]:click here~~ [题目大意]: n个人排队,f表示女,m表示男,包含子串'fmf'和'fff'的序列为O队列,否则为E队列,有多少个序列为E队列. [思路]: 用f(n)表示n个人满足条件的结果,那么如果最后一个人是m的话,那么前n-1个满足条件即可,就是f(n-1): 如果最后一个是f那么这个还无法推出结果,那么往前再考虑一位:那么后三位可能是:mmf, fmf, mff, fff,其中fff和fmf不满足题意所以我们不考虑,但是如果是 mmf的话那么前n-3可以找满足

算法笔记--矩阵快速幂

写的不错的博客:http://www.cnblogs.com/yan-boy/archive/2012/11/29/2795294.html 优点:根据数列递推式快速计算数列an的值(当n很大时) 步骤:由数列递推式构造矩阵,然后用矩阵快速幂计算矩阵的幂. 构造矩阵:对于an =x*an-1 +y*an-2 ,可以构造矩阵为: [an ,an-1]=[an-1 ,an-2]*A A=[x 1 y 0]; 矩阵快速幂模板: #include<iostream> #include<cstri

点头OJ 1033 . 骨牌覆盖 V2 ( 状态压缩 + 矩阵快速幂 )

做题感悟:先前做过一个类似的题,是俄罗斯的一道区域赛的题目,也是用的状态压缩 + 矩阵快速幂. 解题思路:状态压缩 + 矩阵快速幂 构造一个矩阵 B [ i ] [ j ] 代表状态 i ,与状态 j 是否合法,j 代表上一行的状态,如果合法为 1 ,否则为 0 ,这样如果再得到初始各种状态的方案数的矩阵 A ,A 只有一列 ,这样 B * A 就是第二行各种状态对应 的方案数 .这样再加上矩阵快速幂就解决了. 代码: #include<iostream> #include<sstrea

矩阵快速幂小结

矩阵 并不想扯什么高端线代的内容因为我也不会 定义 由$n \times m$个数$a_{ij}$排成的$n$行$m$列的数表称为$n$行$m$列的矩阵,简称$n \times m$矩阵. $$A =\begin{bmatrix}a_{11} & a_{12} & \dots a_{1m} \\ a_{21}, & \dots & \dots \\ a_{31}, & \dots & \dots \\ a_{41} & \dots & a_{