Uva 11551 - Experienced Endeavour ( 矩阵快速幂 )

Uva 11551 - Experienced Endeavour ( 矩阵快速幂 )

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define MAX_SIZE 50
#define MOD 1000
#define CLR( a, b ) memset( a, b, sizeof(a) )
struct Mat
{
    int n;
    int mat[MAX_SIZE][MAX_SIZE];
    Mat( int _n )
    {
        n = _n;
        CLR( mat, 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( b.n );
        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;
    }
};

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

void Orz()
{
    int n, k, t, x, y;
    scanf( "%d", &t );
    while( t-- )
    {
        scan( n ), scan( k );
        Mat c( n );
        for( int i = 0; i < n; ++i )
            scan( c.mat[i][0] );
        Mat d( n );
        for( int i = 0; i < n; ++i )
        {
            scan( x );
            for( int j = 0; j < x; ++j )
            {
                scan( y );
                d.mat[i][y] = 1;
            }
        }
        Mat res = fast_mod( d, k );
        res = res * c;
        for( int i = 0 ; i < n; ++i )
        {
            if( i != 0 ) putchar( ‘ ‘ );
            printf( "%d",res.mat[i][0] );
        }
        putchar( ‘\n‘ );
    }
}

int main()
{
    Orz();
    return 0;
}

代码君

时间: 2024-10-29 05:38:37

Uva 11551 - Experienced Endeavour ( 矩阵快速幂 )的相关文章

UVA 11551 - Experienced Endeavour(矩阵高速幂)

UVA 11551 - Experienced Endeavour 题目链接 题意:给定一列数,每一个数相应一个变换.变换为原先数列一些位置相加起来的和,问r次变换后的序列是多少 思路:矩阵高速幂,要加的位置值为1.其余位置为0构造出矩阵,进行高速幂就可以 代码: #include <cstdio> #include <cstring> const int N = 55; int t, n, r, a[N]; struct mat { int v[N][N]; mat() {mem

UVA 10655 - Contemplation! Algebra(矩阵快速幂)

UVA 10655 - Contemplation! Algebra 题目链接 题意:给定p, q, n代表p=a+b,q=ab求an+bn 思路:矩阵快速幂,公式变换一下得到(an+bn)(a+b)=an+1+bn+1+ab(an?1+bn?1),移项一下得到an+1+bn+1=(an+bn)p?q(an?1+bn?1) 这样就可以用矩阵快速幂求解了 代码: #include <stdio.h> #include <string.h> long long p, q, n; str

UVA 11551 Experienced Endeavour

矩阵快速幂. 题意事实上已经告诉我们这是一个矩阵乘法的运算过程. 构造矩阵:把xi列的bij都标为1. 例如样例二: #include<cstdio> #include<cstring> #include<cmath> #include<vector> #include<algorithm> using namespace std; long long const MOD = 1000; int n, m; long long a[50 + 5]

UVA 11551 - Experienced Endeavour(构造矩阵-水题)

题意:求一列序列的经过r次变化后的新序列,这些变化都是旧序列的某些已给位置的和产生新的项 思路:好水,直接构造01矩阵 //Accepted 45 ms C++ 4.8.2 1442 #include<cstdio> #include<iostream> #include<cstring> #include<algorithm> using namespace std; const int mod= 1000; int num[55]; int res[55

UVA - 10229 - Modular Fibonacci (矩阵快速幂 + fibonacci)

题目传送:UVA - 10229 思路:就是简单的矩阵快速幂求fibonacci数列,然后注意可能中间结果会爆int,因为2^19有50多万 AC代码: #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <cmath> #include <queue> #include <stack> #includ

uva 11651 - Krypton Number System(矩阵快速幂)

题目链接:uva 11651 - Krypton Number System 题目大意:给定进制base,和分数score,求在base进制下,有多少个数的值为score,要求不能有连续相同的数字以及前导0.计算一个数的值即为相邻两位数的平方差和. 解题思路:因为score很大,所以直接dp肯定超时,但是即使对于base=6的情况,每次新添一个数score最大增加25(0-5),所以用dp[i][j]预处理出base平方以内的总数,然后用矩阵快速幂计算. #include <cstdio> #

UVA 11651 - Krypton Number System(DP+矩阵快速幂)

UVA 11651 - Krypton Number System 题目链接 题意:给一个进制base,一个分数score求该进制下,有多少数满足一下条件: 1.没有连续数字 2.没有前导零 3.分数为score,分数的计算方式为相邻数字的平方差的和 思路:先从dp入手,dp[i][j]表示组成i,最后一个数字为j的种数,然后进行状态转移,推出前面一步能构成的状态,也就是到dp[(b - 1) * (b - 1)][x]. 然后可以发现后面的状态,都可以由前面这些状态统一转移出来,这样就可以利用

UVA 10870 - Recurrences(矩阵快速幂)

UVA 10870 - Recurrences 题目链接 题意:f(n) = a1 f(n - 1) + a2 f(n - 2) + a3 f(n - 3) + ... + ad f(n - d), for n > d. 已知前d项求第n项 思路:矩阵快速幂,对应矩阵为 |a1 a2 a3 ... ad| |1 0 0 ... 0 0 0| |0 1 0 ... 0 0 0| |0 0 1 ... 0 0 0| |0 0 0 ... 0 0 0| |0 0 0 ... 1 0 0| |0 0 0

uva 10743 - Blocks on Blocks(矩阵快速幂)

题目链接:uva 10743 - Blocks on Blocks 题目大意:问说n联骨牌有多少种,旋转镜像后相同不算同一组,一行的格子必须连续,如果答案大于10000,输出后四位. 解题思路:想了一下午的递推式,实在受不了,把推出的序列在网上搜了一下,有公式ai=5?ai?1?7?ai?2+4?ai?3 (i≥5) PS:哪位神人知道怎么推出来的请留言我,大恩不言谢~ #include <cstdio> #include <cstring> #include <algori