HDU1005 Number Sequence
1 #include<stdio.h> 2 void fast_pow(int a[][2], int b[][2]) 3 { 4 int c[2][2]; 5 6 c[0][0] = (a[0][0]*b[0][0] + a[0][1] * b[1][0]) % 7; 7 c[0][1] = (a[0][0]*b[0][1] + a[0][1] * b[1][1]) % 7; 8 c[1][0] = (a[1][0]*b[0][0] + a[1][1] * b[1][0]) % 7; 9 c[1][1] = (a[1][0]*b[0][1] + a[1][1] * b[1][1]) % 7; 10 11 a[0][0]=c[0][0]; 12 a[0][1]=c[0][1]; 13 a[1][0]=c[1][0]; 14 a[1][1]=c[1][1]; 15 } 16 int main() 17 { 18 int A,B,n; 19 int a[2][2],b[2][2]; 20 while (scanf("%d%d%d", &A,&B,&n) , n || A || B) { 21 a[0][0]=A; 22 a[0][1]=B; 23 a[1][0]=b[0][0]=b[1][1]=1; 24 a[1][1]=b[0][1]=b[1][0]=0; 25 n--; 26 while (n){ 27 if (n & 1) 28 fast_pow(b, a); 29 fast_pow(a, a); 30 n >>= 1; 31 } 32 printf ("%d\n", (b[1][0]+b[1][1])%7);//因为忘了对7求余,贡献好几个WA 33 } 34 return 0; 35 }
快速幂的典型例题,本题还可以利用求循环阶来求!代码如下:
1 /* 2 循环阶最大为49,因为每一个f[i]都有它前面的两个f[i-1]和f[i-2]决定, 3 而每个f[i-1]和f[i-2]的取值范围都是0~6共七个,所以f[i]的变换范围是7*7=49个, 4 所以循环阶一定不超过49. 5 */ 6 #include <stdio.h> 7 #include <string.h> 8 #include <math.h> 9 int f[50]; 10 int main() 11 { 12 int a,b,n,i,j; 13 int k[7][7]; 14 f[1]=1;f[2]=1; 15 while (scanf("%d%d%d",&a,&b,&n),a||b||n) 16 { 17 memset(k,0,sizeof(k)); 18 k[1][1]=2; 19 for (i=3;i<=50;i++) 20 { 21 f[i]=a*f[i-1]+b*f[i-2]; 22 f[i]%=7; 23 if (k[f[i]][f[i-1]]) break; 24 k[f[i]][f[i-1]]=i; 25 } 26 j=i-k[f[i]][f[i-1]];//计算机循环阶 27 n-=k[f[i]][f[i-1]];//先减去循环阶前的乱序部分 28 n%=j; 29 if (n==0) n+=j;//如果恰好是0,需加1 30 n+=k[f[i]][f[i-1]];//最后再加上刚才减去的部分 31 printf("%d\n",f[n]); 32 } 33 }