• 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 <= 1018), You should solve for
    g(g(g(n))) mod 109 + 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 }
  • 相关阅读:
    [十二省联考2019]字符串问题:后缀数组+主席树优化建图
    HAOI2018简要题解
    使用单调队列维护决策三元组实现决策单调性优化DP的一些细节
    杜教筛&min_25筛复习
    分治NTT:我 卷 我 自 己
    高级(并不)多项式算法总结
    导数与微分简单总结(updated)
    退役前的做题记录
    USACO2018DEC PLATINUM
    USACO2018DEC GOLD
  • 原文地址:https://www.cnblogs.com/acSzz/p/2694149.html
Copyright © 2020-2023  润新知