首页 > 代码库 > FZU 1911 Construct a Matrix ( 矩阵快速幂 + 构造 )

FZU 1911 Construct a Matrix ( 矩阵快速幂 + 构造 )

 

FZU 1911 Construct a Matrix (  矩阵快速幂 + 构造 )

 

题意:需要构造一个矩阵满足如下要求:1.矩阵是一个S(N)*S(N)的方阵2.S(N)代表斐波那契数列的前N项和模上M3.矩阵只能由1, 0, -1组成4.矩阵每行每列的和不能相等Here, the Fibonacci numbers are the numbers in the followingsequence: 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, …

 

 

分析:1.可以发现,如果S(N) 为奇数,无法构造,直接输出No2.可以用一个3*3的矩阵通过矩阵快速幂来解决斐波那契数列前N项和问题3.4. 这个倒是真的不知道怎么构造。。。FZU大神的构造方法,,太牛了上三角全为1下三角全为-1对角线为 1 0 交替

S(N) = 4,构造如下

1 1 1 1
1 1 0 -1
1 1 -1 -1
0 -1 -1 -1

 

 

代码
/* ***********************************************Problem       :FZU 1911 Construct a MatrixFile Name     :Author        :Created Time  :2014-10-21 13:58:53 ************************************************ */#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 MAX_SIZE 3int m, n, r;int M[MAX_SIZE];inline void scan( int &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];    void zero()    {        for( int i = 0; i < 3; ++i )            for( int j = 0; j < 3; ++j )                mat[i][j] = 0;    }    void init()    {        for( int i = 0; i < 3; ++i )            for( int j = 0; j < 3; ++j )                mat[i][j] = ( i == j );    }    void setv( int v )    {        for( int i = 0; i < 3; ++i )            for( int j = 0; j < 3; ++j )                mat[i][j] = v;    }    Mat operator * (const Mat &b) const    {        Mat c;        c.zero();        for( int k = 0; k < 3; ++k )            for( int i = 0; i < 3; ++i ) if( mat[i][k] )                for( int j = 0; j < 3; ++j )                    c.mat[i][j] = ( c.mat[i][j] + mat[i][k] * b.mat[k][j] ) % m;        return c;    }    void debug()    {        for( int i = 0; i < 3; ++i )        {            for( int j = 0; j < 3; ++j )            {                if( j != 0 )    putchar(   );                printf( "%lld", mat[i][j] );            }            putchar( \n );        }    }};Mat fast_mod( Mat a, int b ){    Mat res;    res.init();    while( b )    {        if( b & 1 )   res = res * a;        a = a * a;        b >>= 1;    }    return res;}void Orz(){    //freopen( "1.txt", "r", stdin );    //freopen( "2.txt", "w", stdout );     int cas = 0, t;    scan( t );    while( t-- )    {        scan( n ); scan( m );        if( n == 1 )            r = 1;        else if( n == 2 )            r = 2 % m;        else        {            Mat c;            c.setv(1);            c.mat[0][0] = c.mat[0][2] = c.mat[1][2] = 0;            //c.debug();            c = fast_mod( c, n-2 );            //c.debug();            r = 0;            M[0] = M[1] = 1, M[2] = 2;                        for( int i = 0; i < 3; ++i )                r = ( r + c.mat[2][i] * M[i] ) % m ;            }        printf( "Case %d: ", ++cas );        if( r == 0 || r & 1 )            puts( "No" );        else        {            puts( "Yes" );            int out[210][210];            for( int i = 0; i < r; ++i )            {                for( int j = 0; j < r-i; ++j )                {                    out[i][j] = 1;                }            }            for( int i = 0; i < r; ++i )            {                for( int j = 0; j < i; ++j )                {                    out[i][r-1-j] = -1;                }            }            int flag = 1;            for( int i = 0; i < r; ++i )            {                for( int j = 0; j < r; ++j )                {                    if( i == r - j - 1 )                    {                        if( flag )    out[i][j] = 1;                        else        out[i][j] = 0;                        flag ^= 1;                    }                }            }            for( int i = 0; i < r; ++i )            {                for( int j = 0; j < r ; ++j )                {                    if( j != 0 ) putchar(   );                    printf( "%d", out[i][j] );                }                putchar( \n );            }                    }    }}int main(){    Orz();    return 0;}
代码君

 

FZU 1911 Construct a Matrix ( 矩阵快速幂 + 构造 )