矩阵快速幂刷题系列

来源自http://blog.csdn.net/chenguolinblog/article/details/10309423

hdu 1575

Tr A

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5587    Accepted Submission(s): 4200

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<bits/stdc++.h>
 2 #define clr(x) memset(x,0,sizeof(x))
 3 #define LL long long
 4 #define mod 9973
 5 using namespace std;
 6 typedef vector<LL> vec;
 7 typedef vector<vec> mat;
 8 mat mul(const mat &a,const mat &b)
 9 {
10     int row=a.size();
11     int col=b[0].size();
12     int mid=b.size();
13     mat c(row,vec(col));
14     for(int i=0;i<row;i++)
15         for(int j=0;j<col;j++)
16             for(int k=0;k<mid;k++)
17                 c[i][j]=(c[i][j]+a[i][k]*b[k][j]%mod)%mod;
18     return c;
19 }
20 mat quick_pow(mat a,LL n)
21 {
22     int len=a.size();
23     mat res(len,vec(len));
24     for(int i=0;i<len;i++)
25         res[i][i]=1;
26     while(n)
27     {
28         if(n&1)
29             res=mul(res,a);
30         a=mul(a,a);
31         n>>=1;
32     }
33     return res;
34 }
35 int main()
36 {
37     int T,n;
38     LL k,ansed;
39     scanf("%d",&T);
40     while(T--)
41     {
42         scanf("%d%lld",&n,&k);
43         mat ans(n,vec(n));
44         for(int i=0;i<n;i++)
45             for(int j=0;j<n;j++)
46                 scanf("%lld",&ans[i][j]);
47         ans=quick_pow(ans,k);
48         ansed=0;
49         for(int i=0;i<n;i++)
50             ansed=(ans[i][i]+ansed)%mod;
51         printf("%lld\n",ansed);
52     }
53     return 0;
54 }

hdu 1757

A Simple Math Problem

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

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


裸矩阵快速幂。

 1 #include<bits/stdc++.h>
 2 #define clr(x) memset(x,0,sizeof(x))
 3 #define LL long long
 4 using namespace std;
 5 typedef vector<LL> vec;
 6 typedef vector<vec> mat;
 7 int a[20];
 8 LL m,k,p,n;
 9 mat mul(const mat &a,const mat &b,LL mod)
10 {
11     mat c(a.size(),vec(b[0].size()));
12     for(int i=0;i<a.size();i++)
13         for(int j=0;j<b[0].size();j++)
14             for(int k=0;k<b.size();k++)
15             {
16                 c[i][j]=(c[i][j]%mod+a[i][k]*b[k][j]%mod)%mod;
17             }
18     return c;
19 }
20 mat quick_pow(mat a,LL n,LL mod)
21 {
22     int sized=a.size();
23     mat res(sized,vec(sized));
24     for(int i=0;i<10;i++)
25         res[i][i]=1;
26     while(n)
27     {
28         if(n&1)
29         {
30             res=mul(res,a,mod);
31         }
32         n>>=1;
33         a=mul(a,a,mod);
34     }
35     return res;
36 }
37 int main()
38 {
39     while(scanf("%lld%lld",&n,&m)!=EOF)
40     {
41         for(int i=0;i<10;i++)
42             scanf("%lld",&a[i]);
43         if(n<10)
44         {
45             printf("%lld\n",n%m);
46             continue;
47         }
48         mat multi(10,vec(10));
49         mat ans(1,vec(10));
50         for(int i=0;i<10;i++)
51         {
52             ans[0][i]=i;
53             multi[i][9]=a[9-i];
54         }
55         for(int i=0;i<9;i++)
56             multi[i+1][i]=1;
57         multi=quick_pow(multi,n-9,m);
58         ans=mul(ans,multi,m);
59         printf("%lld\n",ans[0][9]);
60     }
61     return 0;
62 }

时间: 2024-12-15 05:21:04

矩阵快速幂刷题系列的相关文章

hdu 1575 求一个矩阵的k次幂 再求迹 (矩阵快速幂模板题)

Problem DescriptionA为一个方阵,则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 Input22 21 00 13 999999991 2 34

POJ_Fibonacci POJ_3070(矩阵快速幂入门题,附上自己写的矩阵模板)

Fibonacci Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10521   Accepted: 7477 Description In the Fibonacci integer sequence, F0 = 0, F1 = 1, and Fn = Fn − 1 + Fn − 2 for n ≥ 2. For example, the first ten terms of the Fibonacci sequenc

hdu 2604 矩阵快速幂模板题

/* 矩阵快速幂: 第n个人如果是m,有f(n-1)种合法结果 第n个人如果是f,对于第n-1和n-2个人有四种ff,fm,mf,mm其中合法的只有fm和mm 对于ffm第n-3个人只能是m那么有f(n-4)种 对于fmm那么对于第n-3个人没有限制有f(n-3)种 顾f(n)=f(n-1)+f(n-3)+f(n-4); 求出前四个结果分别是 a[1]=2;a[2]=4;a[3]=6;a[4]=9; A=|a[4],a[3],a[2],a[1]| 可以构造矩阵 |1 1 0 0 | B= |0

CodeForces 450B (矩阵快速幂模板题+负数取模)

题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=51919 题目大意:斐波那契数列推导.给定前f1,f2,推出指定第N项.注意负数取模的方式:-1%(10^9+7)=10^9+6. 解题思路: 首先解出快速幂矩阵.以f3为例. [f2]  * [1 -1] = [f2-f1]=[f3]  (幂1次) [f1]  * [1  0]     [f2]      [f2] 于是fn=[f2] *[1 -1]^(n-2)

Foj1683矩阵快速幂水题

Foj 1683 纪念SlingShot 题目链接:http://acm.fzu.edu.cn/problem.php?pid=1683 题目:已知 F(n)=3 * F(n-1)+2 * F(n-2)+7 * F(n-3),n>=3,其中F(0)=1,F(1)=3,F(2)=5,对于给定的每个n,输出F(0)+ F(1)+ -- + F(n) mod 2009.直接构造矩阵就好了,这个矩阵还是很好构造的. 求左边的矩阵矩阵的n-2次幂,和右边的矩阵想成就可以了. //Author: xiaow

poj 3070 矩阵快速幂简单题

基本运用,基本是模板题. 求fi[n].       (1,1)    *( 1  ) ( 1,0)     (  0) #include<iostream> #include<cstring> using namespace std; struct juz { int bat[3][3]; int x,y; //行 列 }; juz mutp(juz a,juz b) { juz c; c.x=a.x;c.y=b.y; memset(c.bat,0,sizeof(c.bat));

HDU1757又是一道矩阵快速幂模板题

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1757 按照题目的要求构造矩阵 //Author: xiaowuga //矩阵: //a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 9 // 1 0 0 0 0 0 0 0 0 0 8 // 0 1 0 0 0 0 0 0 0 0 7 // 0 0 1 0 0 0 0 0 0 0 6 // 0 0 0 1 0 0 0 0 0 0 5 // 0 0 0 0 1 0 0 0 0 0 4 //

POJ3070:Fibonacci(矩阵快速幂模板题)

http://poj.org/problem?id=3070 #include <iostream> #include <string.h> #include <stdlib.h> #include <cstdio> #include <algorithm> #define mod 10000 using namespace std; struct m { int a[3][3]; } init,res; int n; m Mult(m x,m

HDU1575:Tr A(矩阵快速幂模板题)

http://acm.hdu.edu.cn/showproblem.php?pid=1575 #include <iostream> #include <string.h> #include <stdlib.h> #include <cstdio> #include <algorithm> #define mod 9973 using namespace std; struct matrix { int a[11][11]; } init,res