洛谷P3758:[TJOI2017]可樂
阿新 • • 發佈:2018-01-29
sca gpo -m 範圍 opera n+1 兩個 matrix 快速冪
題目描述
加裏敦星球的人們特別喜歡喝可樂。因而,他們的敵對星球研發出了一個可樂機器人,並且放在了加裏敦星球的1號城市上。這個可樂機器人有三種行為: 停在原地,去下一個相鄰的城市,自爆。它每一秒都會隨機觸發一種行為。現 在給加裏敦星球城市圖,在第0秒時可樂機器人在1號城市,問經過了t秒,可樂機器人的行為方案數是多少?
輸入輸出格式
輸入格式
第一行輸入兩個正整數況N,M,N表示城市個數,M表示道路個數。(1 <= N <=30,0 < M < 100)
接下來M行輸入u,v,表示u,v之間有一條道路。(1<=u,v <= n)保證兩座城市之間只有一條路相連。
最後輸入入時間t
輸出格式
輸出可樂機器人的行為方案數,答案可能很大,請輸出對2017取模後的結果。
輸入輸出樣例
輸入樣例#1
3 2
1 2
2 3
2
輸出樣例#1
8
說明
【樣例解釋】
1 ->爆炸
1 -> 1 ->爆炸
1 -> 2 ->爆炸
1 -> 1 -> 1
1 -> 1 -> 2
1 -> 2 -> 1
1 -> 2 -> 2
1 -> 2 -> 3
【數據範圍】
對於20%的pn,有1 < t ≤ 1000
對於100%的pn,有1 < t ≤ 10^6。
想法
很顯然的dp
n這麽小,可以矩陣加速
進行快速冪的矩陣共n+1列,前n列為某個點與其他點的連接情況,最後一列全是1,計算某一秒自爆的方案數
代碼
#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #define P 2017 using namespace std; const int N = 35; struct matrix{ int a[N][N]; void clear(){ for(int i=1;i<N;i++) for(int j=1;j<N;j++) a[i][j]=(i==j); } matrix operator * (const matrix &b) const{ matrix c; for(int i=1;i<N;i++) for(int j=1;j<N;j++){ c.a[i][j]=0; for(int k=1;k<N;k++) c.a[i][j]=(c.a[i][j]+(a[i][k]*b.a[k][j])%P)%P; } return c; } }; int n,m,t; matrix map; matrix pow_mod(matrix b,int x){ matrix ret; ret.clear(); while(x){ if(x&1) ret=ret*b; b=b*b; x>>=1; } return ret; } int main() { int u,v; scanf("%d%d",&n,&m); map.clear(); for(int i=0;i<m;i++){ scanf("%d%d",&u,&v); map.a[u][v]=map.a[v][u]=1; } for(int i=1;i<=n+1;i++) map.a[i][n+1]=1; scanf("%d",&t); matrix a; memset(a.a,0,sizeof(a.a)); a.a[1][1]=1; a=a*pow_mod(map,t); int ans=0; for(int i=1;i<=n+1;i++) ans=(ans+a.a[1][i])%P; printf("%d\n",ans); return 0; }
洛谷P3758:[TJOI2017]可樂