码迷,mamicode.com
首页 > 其他好文 > 详细

矩阵快速幂刷题系列

时间:2017-08-28 23:59:04      阅读:429      评论:0      收藏:0      [点我收藏+]

标签:names   log   lld   long   ble   nes   logs   osi   lease   

来源自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 }
View Code

 

 

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 }
View Code

 

矩阵快速幂刷题系列

标签:names   log   lld   long   ble   nes   logs   osi   lease   

原文地址:http://www.cnblogs.com/wujiechao/p/7442261.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!