HDU 4291 A Short problem(找循环节+快速幂矩阵)

题目链接

在知道算法的情况下,写了矩阵的算法去找循环节,跑了10来分钟没出结果。。。真心2B啊。。。好好理解这种利用循环节的优化。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <cstdlib>
 6 using namespace std;
 7 #define LL __int64
 8 int len1 = 222222224,len2 = 183120;
 9 LL p[3][3],mat[3][3];
10 LL qmod(LL n,LL MOD)
11 {
12     int i,j,k;
13     LL c[3][3];
14     while(n)
15     {
16         if(n&1)
17         {
18             memset(c,0,sizeof(c));
19             for(i = 1; i <= 2; i ++)
20                 for(j = 1; j <= 2; j ++)
21                     for(k = 1; k <= 2; k ++)
22                     {
23                         c[i][j] = (c[i][j]+(mat[i][k]*p[k][j])%MOD)%MOD;
24                     }
25             memcpy(mat,c,sizeof(mat));
26         }
27         memset(c,0,sizeof(c));
28         for(i = 1; i <= 2; i ++)
29             for(j = 1; j <= 2; j ++)
30                 for(k = 1; k <= 2; k ++)
31                 {
32                     c[i][j] = (c[i][j]+(p[i][k]*p[k][j])%MOD)%MOD;
33                 }
34         memcpy(p,c,sizeof(p));
35         n >>= 1;
36     }
37     return mat[1][1]%MOD;
38 }
39 int main()
40 {
41     int i,j,k;
42     LL n;
43 
44     while(scanf("%I64d",&n)!=EOF)
45     {
46         for(k = 1; k <= 3; k ++)
47         {
48             memset(p,0,sizeof(p));
49             memset(mat,0,sizeof(mat));
50             p[1][1] = 3;
51             p[1][2] = p[2][1] = 1;
52             p[2][2] = 0;
53             for(i = 1; i <= 2; i ++)
54                 for(j = 1; j <= 2; j ++)
55                     if(i == j)
56                         mat[i][j] = 1;
57                     else
58                         mat[i][j] = 0;
59             if(n == 0||n == 1)
60             {
61                 continue;
62             }
63             if(k == 1)
64             n = qmod(n-1,len2);
65             else if(k == 2)
66             n = qmod(n-1,len1);
67             else if(k == 3)
68             n = qmod(n-1,1000000007);
69         }
70         printf("%I64d\n",n);
71     }
72     return 0;
73 }
74 //找寻环节的程序
75 /*
76 #include <stdio.h>
77 int main()
78 {
79     LL i,j,k,t;
80     j = 1;k = 0;
81     for(i = 2;i <= 1000000000;i ++)
82     {
83         t = j;
84         j = (3*j + k)%222222224;
85         k = t;
86         if(j == 1&&k == 0)
87         {
88             printf("%d\n",i);
89             break;
90         }
91     }
92     return 0;
93 }
94 */
posted @ 2012-09-20 20:15  Naix_x  阅读(198)  评论(0编辑  收藏  举报