• HDU4291—A Short problem


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4291

    题目意思:求g(g(g(n))) mod 109 + 7,其中g(n) = 3g(n - 1) + g(n - 2),g(1) = 1,g(0) = 0。

    思路:一个很简单的矩阵快速幂,简单的想法就是先用n算出g(n),然后再算g(g(n)),然后再算最外层,都是mod(1e9+7),这么做就错了,这道题有一个循环节的问题,看来这种嵌套的递推式取mod是存在循环节的,以后要注意下。

    计算循环节的代码(貌似方法叫做弗洛伊德判圈法?):

     1 #include <cstdio>  
     2 #include <iostream>  
     3 using namespace std;  
     4 #define LL __int64  
     5 LL mod=1e9+7;  
     7 int main()  
     8 {  
     9     LL i,a,b,g;  
    10     a=1,b=0;  
    11     for(i=1;;i++)  
    12     {  
    13         g=(3*a+b)%mod;  
    14         b=a;  
    15         a=g;  
    16         if(a==1&&b==0)  
    17         {  
    18             if(i!=mod) {mod=i;}  
    19             else break;
    20             cout<<i<<endl;  
    21             i=1;
    22         }         
    23     }  
    24     return 0;  
    25 }  

    代码:

     1 #include<cstdio>  
     2 #include<cstring>  
     3 #include<iostream>  
     4 #include<algorithm>  
     5 using namespace std;  
     6   
     7 typedef __int64 int64;  
     8 const int N = 2;  
     9   
    10 int64 n;  
    11 struct Matrix{  
    12     int64 mat[N][N];  
    13     int64 MOD;  
    14     Matrix operator*(const Matrix& m)const{  
    15           Matrix tmp;  
    16           tmp.MOD = MOD;  
    17           for(int i = 0 ; i < N ; i++){  
    18               for(int j = 0 ; j < N ; j++){  
    19                   tmp.mat[i][j] = 0;  
    20                   for(int k = 0; k < N ; k++)  
    21                       tmp.mat[i][j] += mat[i][k]*m.mat[k][j]%MOD;  
    22                   tmp.mat[i][j] %= MOD;  
    23               }  
    24           }  
    25           return tmp;  
    26     }  
    27 };  
    28   
    29 int64 Pow(Matrix m , int64 x , int64 MOD){  
    30     if(x <= 1) return x;  
    31     Matrix ans;  
    32     ans.MOD = m.MOD = MOD;  
    33     ans.mat[0][0] = ans.mat[1][1] = 1;  
    34     ans.mat[1][0] = ans.mat[0][1] = 0;  
    35     x--;  
    36     while(x){  
    37         if(x%2)  
    38             ans = ans*m;  
    39         x /= 2;  
    40         m = m*m;  
    41     }  
    42     return ans.mat[0][0]%MOD;  
    43 }  
    44   
    45 // 暴力找到循环节  
    46 int64 getLoop(int64 MOD){  
    47     int64 pre1 = 1;  
    48     int64 pre2 = 0;  
    49     for(int64 i = 2 ; ; i++){  
    50         int64 x = 3*pre1%MOD+pre2%MOD;  
    51         x %= MOD;  
    52         // update  
    53         pre2 = pre1;  
    54         pre1 = x;  
    55         int64 y = 3*pre1%MOD+pre2%MOD;  
    56         if(x == 0 && y == 1){  
    57             return i;  
    58         }   
    59     }  
    60 }  
    61   
    62 int main(){  
    63     int64 L1 = 1e9+7;   
    64     int64 L2 = 222222224;  
    65     int64 L3 = 183120;  
    66     Matrix m;  
    67     m.mat[0][0] = 3; m.mat[1][1] = 0;  
    68     m.mat[0][1] = 1; m.mat[1][0] = 1;  
    69     while(scanf("%I64d" , &n) != EOF){  
    70          int64 x = Pow(m , n , L3);  
    71          int64 y = Pow(m , x , L2);  
    72          int64 ans = Pow(m , y , L1);  
    73          printf("%I64d
    " , ans);  
    74     }  
    75     return 0;  
    76 }  
    View Code
  • 相关阅读:
    浅析HSTS
    浅析Diffie–Hellman
    SSIM(结构相似度算法)不同实现版本的差异
    某直播App问题分析
    相机与摄影基础
    Macaca-iOS入门那些事2
    Macaca-iOS入门那些事
    iOS instruments trace文件解析方案
    关于QCon2015感想与反思
    深入浅出Android App耗电量统计
  • 原文地址:https://www.cnblogs.com/xiaowuga/p/7353191.html
Copyright © 2020-2023  润新知