zoukankan      html  css  js  c++  java
  • BZOJ4887: [Tjoi2017]可乐 矩阵快速幂

    Description

    加里敦星球的人们特别喜欢喝可乐。因而,他们的敌对星球研发出了一个可乐机器人,并且
    放在了加里敦星球的1号城市上。这个可乐机器人有三种行为:停在原地,去下一个相邻的
    城市,自爆。它每一秒都会随机触发一种行为。现在给出加里敦星球城市图,在第0秒时可
    乐机器人在1号城市,问经过了t秒,可乐机器人的行为方案数是多少?
     

    Input

    第一行输入两个正整数N,M表示城市个数,M表示道路个数。(1≤N≤30,0≤M≤100)
    接下来M行输入u,v表示u,v之间有一条道路。
    (1≤u,v≤n)保证两座城市之间只有一条路相连。
    最后输入时间t。1<t≤10^6

    Output

     输出可乐机器人的行为方案数,答案可能很大,请输出对2017取模后的结果。

    Sample Input

    3 2
    1 2
    2 3
    2

    Sample Output

    8

    Solution

    第一次做到这种以图的形式的递推用矩阵乘法优化的

    貌似是套路题但是我不会啊T_T

    于是观摩了一波题解弄懂了这种类型的题目

    一般是这种T很大N很小的题目就可以矩阵乘法优化

    要求走T次就是对邻接矩阵自乘T次...

    /**************************************************************
        Problem: 4887
        User: henryy
        Language: C++
        Result: Accepted
        Time:80 ms
        Memory:1456 kb
    ****************************************************************/
     
    #include <bits/stdc++.h>
     
    using namespace std ;
     
    #define mod 2017
     
    int n , m ;
    struct matrix {
        int m[ 100 ][ 100 ] ;
        matrix() {
            memset( m , 0 , sizeof( m ) ) ;
        }
        int *operator[] ( int a ) { return m[ a ] ; } 
        matrix operator * ( matrix &x ) {
            matrix ans ;
            memset( ans.m , 0 , sizeof( ans.m ) ) ;
            for( int i = 0 ; i <= n ; i ++ ) {
                for( int j = 0 ; j <= n ; j ++ ) {
                    for( int k = 0 ; k <= n ; k ++ ) {
                        ans[ i ][ j ] = (ans[ i ][ j ] + m[ i ][ k ] * x[ k ][ j ] ) % mod ;
                    }
                }
            }
            return ans ;
        }
    } a ;
     
    matrix power( matrix x , int b ) {
        matrix ans , base = x ;
        for( int i = 0 ; i <= n ; i ++ ) ans[ i ][ i ] = 1 ;
        while( b ) {
            if( b & 1 ) ans = ans * base ;
            base = base * base ;
            b >>= 1 ;
        }
        return ans ;
    }
     
    int main() {
        scanf( "%d%d" , &n , &m ) ;
        for( int i = 1 ; i <= m ; i ++ ) {
            int x , y ;
            scanf( "%d%d" , &x , &y ) ;
            a[ x ][ y ] = a[ y ][ x ] = 1 ;
        }
        int t ;
        scanf( "%d" , &t ) ;
        for( int i = 0 ; i <= n ; i ++ ) a[ i ][ i ] = a[ i ][ 0 ] = 1 ;
        a = power( a , t ) ;
        int ans = 0 ;
        for( int i = 0 ; i <= n ; i ++ ) {
            ans = ( ans + a[ 1 ][ i ] ) % mod ;
        }
        printf( "%d
    " , ans ) ;
    }
  • 相关阅读:
    使用带Arduino IDE & WIZ820io的ATmega1284P
    初学者使用IntellJ IDEA建立Struts2项目
    树状数组
    hdu 4605-Magic Ball Game(树状数组)
    hdu1547之BFS
    面向服务的体系结构(SOA)——(3)关于BPM
    电信运营商移动互联网发展分析
    共享IP云主机(VPS)玩转wdcp
    从 Windows 到 Android: 威胁的持续迁移
    java 存储oracle的clob字段
  • 原文地址:https://www.cnblogs.com/henry-1202/p/BZOJ4887.html
Copyright © 2011-2022 走看看