标签:
30%的数据,满足 2 <= N <= 5 ; 1 <= T <= 30 。
100%的数据,满足 2 <= N <= 10 ; 1 <= T <= 1000000000 。
思路:矩阵快速幂应该是第一个能想到的,但是直接将一个长为9的边拆成9个点,那最坏情况下就有9*9*9个点约等于700多个点,时间复杂度是n*n*n*log(t)前面显然会爆,但是可以这样,把一个点拆成9个点,9个点连成一条链,这样就可以乱搞了,如果一个点x到这个点y有长度为k的边 只要将x连到y前面k-1个点就行(因为连出一条边就减少了一条边)
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #define N 90 5 #define MOD 2009 6 using namespace std; 7 char ch[100][100]; 8 struct mat 9 { 10 long long m[N+1][N+1]; 11 mat(){memset(m,0,sizeof(m));} 12 }; 13 mat operator *(mat a,mat b) 14 { 15 mat ans; 16 for(int i=1;i<=N;i++) 17 { 18 for(int j=1;j<=N;j++) 19 { 20 for(int k=1;k<=N;k++) 21 { 22 ans.m[i][j] = (ans.m[i][j] + a.m[i][k] * b.m[k][j])% MOD; 23 } 24 } 25 } 26 return ans; 27 } 28 mat pow(mat a,long long n) 29 { 30 mat ret; 31 for(int i=1;i<=N;i++)ret.m[i][i]=1; 32 for(;n;n>>=1) 33 { 34 if(n&1)ret = (ret * a); 35 a = (a*a); 36 } 37 return ret; 38 } 39 int main() 40 { 41 int n,t; 42 mat a; 43 scanf("%d%d",&n,&t); 44 for(int i=1;i<=n;i++) 45 { 46 scanf("%s",ch[i]+1); 47 } 48 for(int i=1;i<=n;i++) 49 { 50 for(int j=1;j<=8;j++) 51 { 52 a.m[(i-1)*9+j][(i-1)*9+j+1]=1; 53 } 54 } 55 for(int i=1;i<=n;i++) 56 { 57 for(int j=1;j<=n;j++) 58 { 59 int u = ch[i][j]-‘0‘; 60 if(u!=0) 61 { 62 a.m[(i-1)*9+9][(j-1)*9+(9-u+1)]=1; 63 } 64 } 65 } 66 a = pow(a,t); 67 printf("%lld\n",a.m[9][(n-1)*9+9]); 68 return 0; 69 }
BZOJ 1297: [SCOI2009]迷路 [矩阵快速幂]
标签:
原文地址:http://www.cnblogs.com/philippica/p/4700637.html