nyist 299 Matrix Power Series

在poj上是3233

nyist是299

 

这题就是给你一个矩阵A 求他的A + A^2 + A^2+.....A^n %m

就是一道矩阵的运算

首先看这个式子我们把它进行变化

F = A + A ^2 + A^3+... +A^n

n为偶数是:

   A+A^2+...A^n/2 + A^n/2(A+A^2 +...A^n/2)

n为基数时

  A+A^2+..A^n/2+A^n^/2+1 + A^n/2+1(A+A^2+A^n/2)

计算A^n使用矩阵快速幂

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 
  5 using namespace std;
  6 
  7 typedef struct numb
  8 {
  9     long long  a[35][35];
 10     numb()
 11     {
 12         memset(a,0,sizeof(a));
 13     }
 14 }numb;
 15 
 16 numb x,z,y,tmp;
 17 long long m,n,k;
 18 void print(numb z)
 19 {
 20     int i,j;
 21     for(i = 0 ;i < n;i++)
 22     {
 23 
 24         for(j = 0; j <n ;j++)
 25         printf("%lld ",z.a[i][j]) % m;
 26         printf("\n");
 27     }
 28 }
 29 
 30 
 31 void set_1(numb &tmp)//构建单位矩阵
 32 {
 33     int i = 0;
 34     for(i = 0; i < n; i++)
 35         tmp.a[i][i] = 1;
 36 }
 37 
 38 /*void set_2(numb &tmp)//构建全1矩阵
 39 {
 40     int i = 0;
 41     int j = 0;
 42     for(i = 0; i < n; i++)
 43     for(j = 0; j < n; j++)
 44         tmp.a[i][j]  = 1;
 45 }
 46 */
 47 numb mul(numb q,numb p)//矩阵A*B
 48 {
 49     numb kk;
 50 
 51     int i = 0;
 52     int j = 0;
 53     int k = 0;
 54     long sum = 0;
 55 
 56     for(i = 0; i < n; i++)
 57     for(j = 0; j < n; j++)
 58         {
 59             sum = 0;
 60             for(k = 0; k < n; k++)
 61                 sum += q.a[i][k]*p.a[k][j] % m;
 62 
 63             kk.a[i][j] = sum % m;
 64         }
 65         return kk;
 66 }
 67 
 68 numb add(numb x,numb y)//矩阵A+B
 69 {
 70     numb tmp5;
 71     int i= 0;
 72     int j = 0;
 73     for(i = 0; i < n; i++)
 74     for(j = 0; j < n; j++)
 75      tmp5.a[i][j] = (x.a[i][j]+y.a[i][j]) % m;
 76 
 77      return tmp5;
 78 }
 79 
 80 numb kuaishu(numb x,int kk)//矩阵快速幂
 81 {
 82     numb tmp2;
 83     set_1(tmp2);
 84     while(kk)
 85     {
 86         if(kk&1)
 87         {
 88             tmp2 = mul(tmp2,x);
 89         }
 90         kk >>=1;
 91         x = mul(x,x);
 92     }
 93     return tmp2;
 94 }
 95 
 96 numb sum(numb A,int kk)//求和
 97 {
 98     numb tmp4;
 99     if(kk == 1)
100         {
101             tmp4 = A;
102             return tmp4;
103         }
104     else
105     {
106         numb tmp3 = sum(A,kk/2);
107 
108         if(kk&1)
109         {
110             numb tmp2 = kuaishu(A,kk/2+1);
111 
112             tmp4 = add(add(tmp3,tmp2),mul(tmp2,tmp3));
113         }
114         else
115         {
116             numb tmp5 = kuaishu(A,kk/2);
117             tmp4 = add(tmp3,mul(tmp5,tmp3));
118         }
119 
120         return tmp4;
121     }
122 }
123 
124 int main()
125 {
126     while(scanf("%lld%lld%lld",&n,&k,&m) != EOF)
127     {
128         int i = 0;
129         int j = 0;
130         for(i = 0; i < n; i++)
131         for(j = 0; j < n; j++)
132             scanf("%lld",&x.a[i][j]);
133        z = sum(x,k);
134         print(z);
135     }
136     return 0;
137 }

 

 

posted @ 2013-04-16 13:59  heity  阅读(362)  评论(0编辑  收藏  举报