BZOJ4887: [Tjoi2017]可樂 矩陣快速冪
阿新 • • 發佈:2018-11-06
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^6Output
輸出可樂機器人的行為方案數,答案可能很大,請輸出對2017取模後的結果。
Sample Input
3 21 2
2 3
2
Sample Output
8Solution
第一次做到這種以圖的形式的遞推用矩陣乘法優化的
貌似是套路題但是我不會啊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\n" , ans ) ; }