矩阵快速幂专题

HDU1757
递推式给了,入门裸题。
Code:

#include <bits/stdc++.h>
#pragma comment(linker, “/STACK:1024000000,1024000000”)
#define INF 0x3f3f3f3f
#define LL long long
using namespace std;
LL k ;
int m ;
int b[15];
struct Matrix{
    LL a[12][12];
};
Matrix Mul( Matrix x , Matrix y ){
    Matrix res ;
    memset( res.a , 0 , sizeof(res.a) );
    for( int i = 0 ; i < 10 ; i++ ){
        for( int j = 0 ; j < 10 ; j++ ){
            for( int k = 0 ; k < 10; k++ ){
                res.a[i][j] = ( res.a[i][j] + x.a[i][k] * y.a[k][j] % m ) % m;
            }
        }
    }   
    return res ;
}

Matrix quick( Matrix x , int b ){
    Matrix ans ;
    memset( ans.a , 0 , sizeof(ans.a) );
    for( int i = 0 ; i < 10 ; i++ ) ans.a[i][i] = 1 ;
    while( b ){
        if( b & 1 ){
            ans = Mul( ans , x );
        }
        b >>= 1 ;
        x = Mul( x , x ) ;
    }
    return ans ;
}

int main(){
    while( ~scanf("%lld%d",&k,&m) ){
        if( k < 10 ){
            printf("%d\n",k%m);
            continue ; 
        }
        Matrix mat ;
        memset( mat.a , 0 , sizeof(mat.a) );
        for( int i = 0 ; i < 10 ; i++ ){
            scanf("%d",&mat.a[0][i]);
        }
        for( int i = 1 ; i < 10 ; i++ ){
            mat.a[i][i-1] = 1;
        }
        Matrix s = quick( mat , k - 9 );

        Matrix ans ;
        memset( ans.a , 0 , sizeof(ans.a) );
        for( int i = 0 ; i < 10 ; i++ ) ans.a[i][0] = 9 - i ; 

        LL res = 0;
        for( int i = 0 ; i < 10 ; i++ ){
            res = ( res + s.a[0][i] * ans.a[i][0] ) % m;
        }
        printf("%d\n",res);
    }
    return 0 ;
}

HDU1575
更裸。。
Code:

#include <bits/stdc++.h>
#pragma comment(linker, “/STACK:1024000000,1024000000”)
#define INF 0x3f3f3f3f
#define LL long long
using namespace std;
const int MOD = 9973 ;
struct Matrix{
    LL a[12][12];
};
int n , k ;
Matrix Mul( Matrix x , Matrix y ){
    Matrix ans ;
    memset( ans.a , 0 , sizeof(ans.a) );
    for( int i = 0 ; i < n ; i++ ){
        for( int j = 0 ; j < n ; j++ ){
            for( int k = 0 ; k < n ; k++ ){
                ans.a[i][j] = ( ans.a[i][j] + x.a[i][k] * y.a[k][j] % MOD ) % MOD;
            }
        }
    }
    return ans ;
}

Matrix quick( Matrix a , int b ){
    Matrix ans ;
    memset( ans.a , 0 ,sizeof(ans.a) );
    for( int i = 0 ; i < n ; i++ ) ans.a[i][i] = 1 ;    
    while( b ){
        if( b & 1 ) ans = Mul( ans , a );
        b >>= 1 ;
        a = Mul( a , a );
    } 
    return ans ;
}

int main(){
    int T;
    scanf("%d",&T);
    while( T-- ){
        scanf("%d%d",&n,&k);
        Matrix Mat; 
        memset( Mat.a , 0 , sizeof(Mat.a) );
        for( int i = 0 ; i < n ; i++ ){
            for( int j = 0 ; j < n ; j++ ){
                scanf("%d",&Mat.a[i][j]);
            }
        }
        Matrix res = quick( Mat , k ) ;
        int ans = 0 ;
        for( int i = 0 ; i < n ; i++ ){
            ans = ( ans + res.a[i][i] ) % MOD ;
        }
        printf("%d\n",ans);
    }   
    return 0 ;
}

HDU2604
题意:对于只由数字1和0构成的字符串,给出长度为n的,不含子串101且不含子串111的字符串的个数对m取模的值。
推公式:f[n] 为满足条件的长度n的串的个数
如果最后一个为0,那么结果就是f(n-1) 后面加0,肯定不会出现101,111
如果最后一个为1,还要考虑前面2位必须为00 (f[n-3]), 01(前面必须为0)所以就是f[n-4]
得到:f[n] = f [n-1] + f[n-3] + f[n-4]

Code:

#include <bits/stdc++.h>
#pragma comment(linker, “/STACK:1024000000,1024000000”)
#define INF 0x3f3f3f3f
#define LL long long
using namespace std;
int n , m ;
struct Matrix{
    int a[4][4];
};

Matrix Mul( Matrix x , Matrix y ){
    Matrix ans ;
    memset( ans.a , 0 , sizeof(ans) );
    for( int i = 0 ; i < 4 ; i++ ){
        for( int j = 0 ; j < 4 ; j++ ){
            for( int k = 0 ; k < 4 ; k++ ){
                ans.a[i][j] = ( ans.a[i][j] + x.a[i][k] * y.a[k][j] % m ) % m ;
            }
        }
    }
    return ans ;
}

Matrix quick( Matrix x , int b ){
    Matrix ans;
    memset( ans.a , 0 , sizeof(ans) );
    for( int i = 0 ; i < 4 ; i++ ) ans.a[i][i] = 1 ;
        while( b ){
            if( b & 1 ) ans = Mul( ans , x );
            x = Mul(x,x);
            b >>= 1 ;
        }
        return ans ;
    }

    int main(){
        while( ~scanf("%d%d",&n,&m) ){
            if( n == 0 )      printf("0\n");
            else if( n == 1 ) printf("%d\n",2%m);
            else if( n == 2 ) printf("%d\n",4%m);
            else if( n == 3 ) printf("%d\n",6%m);
            else if( n == 4 ) printf("%d\n",9%m);
            else{
                Matrix ans ;
                memset( ans.a , 0 , sizeof(ans.a) );
                ans.a[0][0] = 1 ; ans.a[0][1] = 0 ; ans.a[0][2] = 1 ; ans.a[0][3] = 1 ;
                ans.a[1][0] = 1 ; ans.a[1][1] = 0 ; ans.a[1][2] = 0 ; ans.a[1][3] = 0 ;
                ans.a[2][0] = 0 ; ans.a[2][1] = 1 ; ans.a[2][2] = 0 ; ans.a[2][3] = 0 ;
                ans.a[3][0] = 0 ; ans.a[3][1] = 0 ; ans.a[3][2] = 1 ; ans.a[3][3] = 0 ;
                Matrix tmp ;
                memset( tmp.a , 0 ,sizeof(tmp.a) );
                tmp.a[0][0] = 9 ; tmp.a[1][0] = 6; tmp.a[2][0] = 4 ; tmp.a[3][0] = 2;
                Matrix t = quick( ans , n - 4 );
                int res = 0 ;
                for( int i = 0 ; i < 4 ; i++ ){
                    res = ( res + t.a[0][i] * tmp.a[i][0] ) % m ;
                }
                printf("%d\n",res);
            }
        }
        return 0 ;
    }

猜你喜欢

转载自blog.csdn.net/FrankAx/article/details/81603870