poj3233

题意:给出矩阵A,求S = A + A2 + A3 + … + Ak

分析:把问题转化以加速,令

B = A  I

      0  I

则B^(k + 1) = A^(k + 1)      I + A + A2 + A3 + … + Ak

                            0                          I

用二分法求B^(k + 1)

View Code
#include < cstdio >
#include
< iostream >
#include
< cstdlib >
#include
< cstring >
using namespace std;

#define maxn 61

struct Matrix
{
int ma[maxn][maxn];
} b, ans;

int n, k, m;

void init()
{
memset(b.ma,
0 , sizeof (b.ma));
memset(ans.ma,
0 , sizeof (ans.ma));
scanf(
" %d%d%d " , & n, & k, & m);
for ( int i = 0 ; i < n; i ++ )
for ( int j = 0 ; j < n; j ++ )
{
scanf(
" %d " , & b.ma[i][j]);
b.ma[i][j]
%= m;
ans.ma[i][j]
= b.ma[i][j];
}
for ( int i = 0 ; i < n; i ++ )
{
b.ma[i][n
+ i] = 1 ;
b.ma[n
+ i][n + i] = 1 ;
ans.ma[i][n
+ i] = 1 ;
ans.ma[n
+ i][n + i] = 1 ;
}
}

void mul(Matrix & a, Matrix & b)
{
Matrix x;

for ( int i = 0 ; i < n * 2 ; i ++ )
for ( int j = 0 ; j < n * 2 ; j ++ )
x.ma[i][j]
= a.ma[i][j];
for ( int i = 0 ; i < n * 2 ; i ++ )
for ( int j = 0 ; j < n * 2 ; j ++ )
{
int sum = 0 ;
for ( int k = 0 ; k < n * 2 ; k ++ )
sum
+= x.ma[i][k] * b.ma[k][j];
a.ma[i][j]
= sum % m;
}
}

void sqr(Matrix & a)
{
Matrix x;

for ( int i = 0 ; i < n * 2 ; i ++ )
for ( int j = 0 ; j < n * 2 ; j ++ )
x.ma[i][j]
= a.ma[i][j];
mul(a, x);
}

void work(Matrix & a, int num)
{
if (num == 1 )
return ;
work(a, num
/ 2 );
sqr(a);
if (num % 2 == 1 )
{
mul(a, b);
}
}

int main()
{
freopen(
" D:\\t.txt " , " r " , stdin);
init();
work(ans, k
+ 1 );
for ( int i = 0 ; i < n; i ++ )
{
if (ans.ma[i][n + i] == 0 )
ans.ma[i][n
+ i] = m;
ans.ma[i][n
+ i] -= 1 ;
}
for ( int i = 0 ; i < n; i ++ )
{
printf(
" %d " , ans.ma[i][n]);
for ( int j = 1 ; j < n; j ++ )
printf(
" %d " , ans.ma[i][j + n]);
printf(
" \n " );
}
return 0 ;
}

你可能感兴趣的:(poj)