HDU 5015 233 Matrix ( 矩阵快速幂 )

 

HDU 5015 233 Matrix (  矩阵快速幂 )

 

 

这是西安网络赛的一题,,但是YY之还是没有搞出来。。

后来学习了,今天写个题解吧

 

题意:

给定一个矩阵的第一列,然后需要推算出第n行第m列的数值

 

分析:

矩阵快速幂搞之

构造矩阵如下(需要再增加233 和 3 两行进行状态转移)



1 0 0 0 0 0 0 0 0 0 1 0      a

1 1 0 0 0 0 0 0 0 0 1 0      b

1 1 1 0 0 0 0 0 0 0 1 0      c

1 1 1 0 0 0 0 0 0 0 1 0      d

1 1 1 1 0 0 0 0 0 0 1 0      e

1 1 1 1 1 0 0 0 0 0 1 0      f

1 1 1 1 1 1 0 0 0 0 1 0      g

1 1 1 1 1 1 1 0 0 0 1 0      h

1 1 1 1 1 1 1 1 0 0 1 0      i

1 1 1 1 1 1 1 1 1 0 1 0      j

1 1 1 1 1 1 1 1 1 1 1 0      k

0 0 0 0 0 0 0 0 0 0 10 1     233

0 0 0 0 0 0 0 0 0 0 0 1      3

 

代码君如下
/* ***********************************************

Problem       :HDU 5015 -- 233 Matrix

File Name     :

Author        :

Created Time  :2014-09-15 13:40:17

************************************************ */

#include <cstdio>

#include <cstring>

#include <iostream>

#include <vector>

#include <list>

#include <queue>

#include <map>

#include <string>

#include <set>

#include <algorithm>

#include <cmath>

#include <ctime>

using namespace std;

typedef long long LL;

typedef unsigned long long ULL;

#define CLR(a,b)     memset( a, b, sizeof(a) )

#define MOD    10000007

#define MAX_SIZE 12

int m, n;

LL M[MAX_SIZE];

inline void scan( LL &x )

{

    char c;

    while( c = getchar(), c < '0' || c > '9' );

    x = c - '0';

    while( c = getchar(), c >= '0' && c <= '9' ) x = x*10 + c - '0';

}



struct Mat

{

    LL mat[MAX_SIZE][MAX_SIZE];

    int n;



    Mat(int _n = 0) : n(_n) {};

    void zero()

    {

        for( int i = 0; i < n; ++i )

            for( int j = 0; j < n; ++j )

                mat[i][j] = 0;

    }

    void init()

    {

        for( int i = 0; i < n; ++i )

            for( int j = 0; j < n; ++j )

                mat[i][j] = ( i == j );

    }

    Mat operator * (const Mat &b) const

    {

        Mat c(n);

        c.zero();

        for( int k = 0; k < n; ++k )

            for( int i = 0; i < n; ++i ) if( mat[i][k] )

                for( int j = 0; j < n; ++j )

                    c.mat[i][j] = ( c.mat[i][j] + mat[i][k] * b.mat[k][j] ) % MOD;

        return c;

    }

    void debug()

    {

        for( int i = 0; i < n; ++i )

        {

            for( int j = 0; j < n; ++j )

            {

                if( j != 0 )    putchar( ' ' );

                printf( "%d", mat[i][j] );

            }

            putchar( '\n' );

        }

    }

};



Mat fast_mod( Mat a, int b )

{

    Mat res(a.n);

    res.init();

    while( b )

    {

        if( b & 1 )   res = res * a;

        a = a * a;

        b >>= 1;

    }

    return res;

}



void Orz()

{

    while( ~scanf( "%d %d", &n, &m ) )    

    {

        for( int i = 0; i < n; ++i )

            scan( M[i] );

        M[n]= 233, M[n+1] = 3;

        Mat t(n+2);

        t.zero();

        for( int i = 0; i < n; ++i )

            for( int j = 0; j <= i; ++j )

                t.mat[i][j] = 1;

        for( int i = 0; i < n; ++i )

            t.mat[i][n] = 1;

        t.mat[n][n] = 10; t.mat[n][n+1] = t.mat[n+1][n+1] = 1;

        //t.debug();

        Mat res(n+2);

        res = fast_mod( t, m );

        //res.debug();

        LL ans = 0;

        for( int i = 0; i < n+2; ++i )

            ans = ( ans + res.mat[n-1][i] * M[i] ) % MOD;

        printf( "%I64d\n", ans );

    }

}



int main()

{

    Orz();

    return 0;

}
代码君

 

你可能感兴趣的:(Matrix)