POJ3233:Matrix Power Series

对n<=30(其实可以100)大小的矩阵A求A^1+A^2+……+A^K,K<=1e9,A中的数%m。

从K的二进制位入手。K分解二进制,比如10110,令F[i]=A^1+A^2+……+A^(2^i),那么答案就是F[10000]*A^110+F[100]*A^10+F[10]+A^0。也就是说如果知道F就可以得答案。

F亦可递推,F[i]=F[i-1]*(A^(2^i-1)+A^0)。完美!什么log方,都是假的!

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<algorithm>
 4 #include<math.h>
 5 //#include<iostream>
 6 using namespace std;
 7 
 8 int n,K,mod;
 9 #define maxn 111
10 #define LL long long
11 typedef LL mat[maxn][maxn];
12 mat f,a,last,tmp,t,ans,E;
13 void init(mat &a)
14 {
15     memset(a,0,sizeof(a));
16     for (int i=1;i<=n;i++) a[i][i]=1;
17 }
18 void add(mat a,mat b,mat &ans)
19 {
20     for (int i=1;i<=n;i++)
21         for (int j=1;j<=n;j++)
22             ans[i][j]=(a[i][j]+b[i][j])%mod;
23 }
24 void mul(mat a,mat b,mat &ans)
25 {
26     mat t;
27     memset(t,0,sizeof(t));
28     for (int i=1;i<=n;i++)
29         for (int j=1;j<=n;j++)
30             for (int k=1;k<=n;k++)
31                 t[i][j]=(t[i][j]+a[i][k]*b[k][j]%mod)%mod;
32     for (int i=1;i<=n;i++)
33         for (int j=1;j<=n;j++)
34             ans[i][j]=t[i][j];
35 }
36 int main()
37 {
38     scanf("%d%d%d",&n,&K,&mod);
39     for (int i=1;i<=n;i++)
40         for (int j=1;j<=n;j++)
41             scanf("%lld",&a[i][j]),tmp[i][j]=f[i][j]=a[i][j];
42     init(last);init(E);
43     memset(ans,0,sizeof(ans));
44     while (K)
45     {
46         if (K&1)
47         {
48             mul(f,last,t);
49             add(ans,t,ans);
50             mul(last,tmp,last);
51         }
52         add(tmp,E,t);
53         mul(f,t,f);
54         mul(tmp,tmp,tmp);
55         K>>=1;
56     }
57     for (int i=1;i<=n;i++)
58     {
59         for (int j=1;j<=n;j++)
60             printf("%lld ",ans[i][j]);
61         puts("");
62     }
63     return 0;
64 }
View Code

 

posted @ 2017-08-30 21:28  Blue233333  阅读(121)  评论(0编辑  收藏  举报