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

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

题意:

需要构造一个矩阵满足如下要求:

1.矩阵是一个S(N)*S(N)的方阵
2.S(N)代表斐波那契数列的前N项和模上M
3.矩阵只能由1, 0, -1组成
4.矩阵每行每列的和不能相等
Here, the Fibonacci numbers are the numbers in the following
sequence: 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, …
分析:

1.可以发现,如果S(N) 为奇数,无法构造,直接输出No
2.可以用一个3*3的矩阵通过矩阵快速幂来解决斐波那契数列前N项和问题
3.4. 这个倒是真的不知道怎么构造。。。

FZU大神的构造方法,,太牛了

上三角全为1
下三角全为-1
对角线为 1 0 交替

S(N) = 4,构造如下

1  1  1  11  1  0 -11  1 -1 -10 -1 -1 -1
代码

/* ***********************************************
Problem       :FZU 1911 Construct a Matrix
File 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 3

int 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;
}

代码君

时间: 2024-08-02 11:03:20

FZU 1911 Construct a Matrix ( 矩阵快速幂 + 构造 )的相关文章

FZU 1911 Construct a Matrix

矩阵快速幂+构造. 首先我们要计算出需要构造的矩阵大小是多少,这个可以构造矩阵,进行矩阵快速幂求得. S[n]就是求得的矩阵大小. 接下来就是构造答案了:如果S[n]是奇数或者0,显然无解. 偶数的话,可以构造答案,下面以6*6为例: 下三角全是-1,上三角全是1,对角线上-1与0间隔填写. #include<cstdio> #include<cstring> #include<cmath> #include<vector> #include<algo

Uva 11149 - Power of Matrix ( 矩阵快速幂 )

Uva 11149 -Power of Matrix ( 矩阵快速幂 ) #include <cstdio> #include <cstring> #define CLR( a, b ) memset( a, b, sizeof(a) ) #define MOD 10 #define MAX_SIZE 40 struct Mat { int r, c; int mat[MAX_SIZE][MAX_SIZE]; Mat( int _r = 0 , int _c = 0 ) { CLR

233 Matrix 矩阵快速幂

In our daily life we often use 233 to express our feelings. Actually, we may say 2333, 23333, or 233333 ... in the same meaning. And here is the question: Suppose we have a matrix called 233 matrix. In the first line, it would be 233, 2333, 23333...

HDU 1575 &amp;&amp; 1757 矩阵快速幂&amp;&amp;构造矩阵入门

HDU 1575 Tr A Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2912    Accepted Submission(s): 2167 Problem Description A为一个方阵,则Tr A表示A的迹(就是主对角线上各项的和),现要求Tr(A^k)%9973. Input 数据的第一行是一个T,表示有T组数据.每组

UVa 11149 Power of Matrix (矩阵快速幂,倍增法或构造矩阵)

题意:求A + A^2 + A^3 + ... + A^m. 析:主要是两种方式,第一种是倍增法,把A + A^2 + A^3 + ... + A^m,拆成两部分,一部分是(E + A^(m/2))(A + A^2 + A^3 + ... + A^(m/2)),然后依次计算下去,就可以分解,logn的复杂度分解,注意要分奇偶. 另一种是直接构造矩阵,,然后就可以用辞阵快速幂计算了,注意要用分块矩阵的乘法. 代码如下: 倍增法: #pragma comment(linker, "/STACK:10

hdu 5015 233 Matrix (矩阵快速幂)

题意: 有一种矩阵,它的第一行是这样一些数:a  0,0 = 0, a 0,1 = 233,a 0,2 = 2333,a 0,3 = 23333... 除此之外,在这个矩阵里, 我们有 a i,j = a i-1,j +a i,j-1( i,j ≠ 0).现在给你 a 1,0,a 2,0,...,a n,0, 你能告诉我a n,m 是多少吗? n,m(n ≤ 10,m ≤ 10 9)输出 a n,m mod 10000007. 思路:首先我们观察n和m的取值范围,会发现n非常小而m却非常大,如果

HDU5015-233 Matrix(矩阵快速幂)

题目链接 题意:给定一个矩阵的第0列的第1到n个数,第一行第1个数开始每个数分别为233, 2333........,求第n行的第m个数. 思路:将第一行的数全部右移一位,用前一列递推出下一列,构造矩阵,类似如下 1 0 0 0 0 0 0 1 10 0 0 0 0 0 0 1 1 0 0 0 0 0 1 1 1 0 0 0 0 1 1 1 1 0 0 0 1 1 1 1 1 0 代码: #include <iostream> #include <cstdio> #include

HDU 5015 233 Matrix(矩阵快速幂)

Problem Description In our daily life we often use 233 to express our feelings. Actually, we may say 2333, 23333, or 233333 ... in the same meaning. And here is the question: Suppose we have a matrix called 233 matrix. In the first line, it would be

hdu 2604 Queuing(矩阵快速幂乘法)

Problem Description Queues and Priority Queues are data structures which are known to most computer scientists. The Queue occurs often in our daily life. There are many people lined up at the lunch time. Now we define that ‘f’ is short for female and