Hard Wuxing |
||
Accepted : 13 | Submit : 166 | |
Time Limit : 1000 MS | Memory Limit : 65536 KB |
题目描述“五行”是中国传统哲学思想,它认为认为大自然的现象由“木、火、土、金、水”这五种气的变化所总括, 不但影响到人的命运,同时也使宇宙万物循环不已。 五行具有相生相克的性质,规律如下:
输入多组样例,每组一个整数n(0≤n≤1018),如果n为0,表示输入结束,这个样例不需要处理。 输出每行输出一个样例的结果,因为数值可能非常大,请将结果对109+7取模。 样例输入1 2 0 样例输出5 10 SourceXTU OnlineJudge |
1 #include<iostream> 2 #include<stdio.h> 3 #include<cstring> 4 #include<cstdlib> 5 #include<queue> 6 using namespace std; 7 typedef __int64 LL; 8 const LL mod = 1000000007; 9 10 struct Matrix 11 { 12 LL mat[6][6]; 13 void Init() 14 { 15 LL cur; 16 int i,j; 17 mat[1][1]=0;mat[1][2]=0;mat[1][3]=1;mat[1][4]=1;mat[1][5]=0; 18 for(i=2;i<=5;i++) 19 { 20 for(j=1;j<=5;j++) 21 { 22 if(j==1) cur=5; 23 else cur=j-1; 24 mat[i][j]=mat[i-1][cur]; 25 } 26 } 27 } 28 }M_hxl; 29 void Matrix_ini(Matrix *cur,LL n) 30 { 31 int i,j; 32 for(i=1;i<=n;i++) 33 for(j=1;j<=n;j++) 34 if(i==j) 35 cur->mat[i][j]=1; 36 else cur->mat[i][j]=0; 37 } 53 Matrix Multiply(Matrix cur,Matrix now,LL len) 54 { 55 Matrix ww; 56 int i,j,k,tmp; 57 memset(ww.mat,0,sizeof(ww.mat)); 58 i=1; 59 for(k=1;k<=len;k++) 60 if(cur.mat[i][k]) 61 { 62 for(j=1;j<=len;j++) 63 if(now.mat[k][j]) 64 { 65 ww.mat[i][j]+=cur.mat[i][k]*now.mat[k][j]; 66 if(ww.mat[i][j]>=mod) 67 ww.mat[i][j]%=mod; 68 } 69 } 70 for(i=2;i<=5;i++) 71 { 72 for(j=1;j<=5;j++) 73 { 74 if(j==1) tmp=5; 75 else tmp=j-1; 76 ww.mat[i][j]=ww.mat[i-1][tmp]; 77 } 78 } 79 return ww; 80 } 81 struct Matrix M_add(Matrix cur,Matrix now,LL len) 82 { 83 Matrix ww; 84 int i,j; 85 memset(ww.mat,0,sizeof(ww.mat)); 86 87 for(i=1;i<=len;i++) 88 for(j=1;j<=len;j++) 89 { 90 ww.mat[i][j]=cur.mat[i][j]+now.mat[i][j]; 91 if(ww.mat[i][j]>=mod) 92 ww.mat[i][j]%=mod; 93 } 94 return ww; 95 } 96 Matrix pow_sum1(Matrix cur,LL n,LL len) 97 { 98 Matrix ww; 99 Matrix_ini(&ww,len); 100 while(n) 101 { 102 if(n&1) 103 { 104 ww=Multiply(ww,cur,len); 105 } 106 n=n>>1; 107 cur=Multiply(cur,cur,len); 108 } 109 return ww; 110 } 111 void solve(LL n) 112 { 113 LL k=0; 114 M_hxl.Init(); 115 M_hxl=pow_sum1(M_hxl,n,5); 116 k=(M_hxl.mat[1][3]+M_hxl.mat[1][4])%mod; 117 k=(k*5)%mod; 118 printf("%I64d\n",k); 119 } 120 int main() 121 { 122 LL n; 123 while(scanf("%I64d",&n)>0) 124 { 125 if(n==0)break; 126 if(n==1) 127 { 128 printf("5\n"); 129 continue; 130 } 131 solve(n-1); 132 } 133 return 0; 134 }