hdu 4291 A Short problem (成都网络赛 矩阵乘法 递推式 求 循环节)

http://acm.hdu.edu.cn/showproblem.php?pid=4291

 题意:

 

A Short problem

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 739    Accepted Submission(s): 277


Problem Description
  According to a research, VIM users tend to have shorter fingers, compared with Emacs users.
  Hence they prefer problems short, too. Here is a short one:
  Given n (1 <= n <= 10 18), You should solve for
g(g(g(n))) mod 10 9 + 7

  where
g(n) = 3g(n - 1) + g(n - 2)

g(1) = 1

g(0) = 0
 

Input
  There are several test cases. For each test case there is an integer n in a single line.
  Please process until EOF (End Of File).
 

Output
  For each test case, please print a single line with a integer, the corresponding answer to this case.
 

Sample Input
   
     
0 1 2
 

Sample Output
   
     
0 1 42837
 

 

 

题解:  首先 看到 它是 三层 求  g(n);  因为  每一层  g(g(n))  与  g(g(n)% 10^9 + 1)  不一定相同 ,所以 我们要 求出  内层的 循环节;

 在 最外层 为  10^9 + 7 的情况下 ,我们 可以 求出 次外 层的 循环节 是  222222224   在将  222222224 带入 可以求出  最内层的 循环节 ,为183120 ;


 1  // 求循环节  
 2  #include <cstdio>  
 3 #include < set>  
 4  const __int64 M =  222222224;  
 5  using  namespace std;  
 6 __int64 a[ 4], b[ 4];  
 7   
 8  int main()  
 9 {  
10      set<__int64> se;  
11     __int64 i;  
12     __int64 f1 =  1, f0 =  0;  
13      for(i =  2; ; ++ i)  
14     {  
15         __int64 f2 = ( 3 * f1 + f0) % M;  
16          if(f1 ==  0 && f2 ==  1break;  
17         f0 = f1; f1 = f2;  
18     }  
19     printf( " %I64d\n ", i -  1);  
20      return  0;  
21 }

 在 矩阵乘法 时由于  将 成的 次数  忘了 变为  long long  的  错了  好几次 。。。。。。。。。。。。。。。。

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<cmath>
  4 #include<iostream>
  5 #include<algorithm>
  6 #include< set>
  7 #include<map>
  8 #include<queue>
  9 #include<vector>
 10 #include< string>
 11  #define Min(a,b) a<b?a:b
 12  #define Max(a,b) a>b?a:b
 13  #define CL(a,num) memset(a,num,sizeof(a));
 14  #define eps  1e-12
 15  #define inf   10000000
 16 
 17 
 18  // freopen("data.txt","r",stdin);
 19  const  double pi  = acos(- 1.0);
 20 typedef   __int64  ll;
 21  const  int maxn =  101000 ;
 22  using  namespace std;
 23  struct   matrix
 24 {
 25     ll m[ 2][ 2];
 26 
 27 };
 28  int n =  2;
 29 ll mod ;
 30 matrix e;
 31  void init()
 32 {
 33    e.m[ 0][ 0] =  1;
 34    e.m[ 0][ 1] =  0;
 35    e.m[ 1][ 0] =  0;
 36    e.m[ 1][ 1] =  1;
 37 }
 38 
 39 matrix mtmul(matrix a,matrix b)
 40 {
 41 
 42     matrix c;
 43      int i,j,k;
 44      for(i =  0; i < n; i++)
 45     {
 46          for(j =  0; j < n;j++)
 47         {
 48             c.m[i][j] =  0;
 49              for(k =  0 ; k < n;k++)
 50             {
 51                 c.m[i][j] += a.m[i][k]* b.m[k][j];
 52                 c.m[i][j] %= mod;
 53             }
 54         }
 55     }
 56 
 57 
 58      return c;
 59 }
 60 matrix mtpow(matrix d, ll k)
 61 {   matrix a;
 62 
 63 
 64     a = e; // e 为单位矩阵
 65      while(k)
 66    {
 67         if(k& 1)
 68        {
 69            a = mtmul(a,d);
 70        }
 71        k/= 2;
 72        d = mtmul(d,d);
 73    }
 74     return a;
 75 
 76 }
 77 
 78  int main()
 79 {
 80     ll  num;
 81     init() ;
 82      // freopen("data.txt","r",stdin);
 83 
 84       // freopen("out.txt","w",stdout);
 85       while(cin>>num)
 86     {
 87 
 88          if(num ==  0){printf( " 0\n "); continue ;}
 89          if(num ==  1){printf( " 1\n "); continue ;}
 90 
 91           matrix a,c,d,b;
 92 
 93         a.m[ 0][ 0] =   3;
 94         a.m[ 0][ 1] =  1;
 95         a.m[ 1][ 0] =  1;
 96         a.m[ 1][ 1]  =  0 ;
 97 
 98         b.m[ 0][ 0] =  1;
 99         b.m[ 0][ 1] =  0;
100         b.m[ 1][ 0] =  0;
101         b.m[ 1][ 1] =  0;
102         mod =  183120 ;
103         c = mtpow(a,num -  1);
104        num = c.m[ 0][ 0] ;
105 
106 
107          if(c.m[ 0][ 0] ==  0){printf( " 0\n "); continue ;}
108          if(c.m[ 0][ 0] ==  1){printf( " 1\n "); continue ;}
109 
110 
111 
112 
113         mod =  222222224 ;
114         c = mtpow(a,num -  1);
115 
116         num = c.m[ 0][ 0] ;
117 
118 
119           if(c.m[ 0][ 0] ==  0){printf( " 0\n "); continue ;}
120          if(c.m[ 0][ 0] ==  1){printf( " 1\n "); continue ;}
121 
122 
123 
124 
125         mod =  1000000007 ;
126         c = mtpow(a,num -  1);
127 
128 
129         num = c.m[ 0][ 0] ;
130           if(c.m[ 0][ 0] ==  0){printf( " 0\n "); continue ;}
131          if(c.m[ 0][ 0] ==  1){printf( " 1\n "); continue ;}
132 
133 
134        cout<<num<<endl;
135 
136     }
137 }

 

 

你可能感兴趣的:(HDU)