zoukankan      html  css  js  c++  java
  • hdu 4291 A Short problem(矩阵+取模循环节)

    A Short problem

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


    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
     

    矩阵非常easy构造

    矩阵A
    1   0
    0   0
    递推矩阵B
    3   1
    1   0
    g(n)=A*B^(n-1)的第1行第1列。

    如今是一个多重函数在最外层取模,n为10^18,当到最外层取模肯定不能够,这时候就要寻找循环节了。首先是最
    外层的模。通过暴力判循环节
    long long x3, x1=0,x2=1;
         long long temp=1000000007;
         for(long long i=2;;i++)
         {
             x3=(3*x2+x1)%temp;
             if(x3==1&&x2==0)
             {
                 printf("%I64d
    ",i-1);
                 break;
             }
             x1=x2;
             x2=x3;
         }

    求出第2层队222222224 取模。同理第3层对183120取模。

    代码:
    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    struct matrix
    {
        long long ma[3][3];
    };
    long long mod[3];
    matrix multi(matrix x,matrix y,long long m)
    {
        matrix ans;
        memset(ans.ma,0,sizeof(ans.ma));
        for(int i=1; i<=2; i++)
        {
            for(int j=1; j<=2; j++)
            {
                if(x.ma[i][j])
                {
                    for(int k=1; k<=2; k++)
                    {
                        ans.ma[i][k]=(ans.ma[i][k]+(x.ma[i][j]*y.ma[j][k])%m)%m;
                    }
                }
            }
        }
        return ans;
    }
    int main()
    {
        long long n;
        while(~scanf("%I64d",&n))
        {
            mod[0]=183120;
            mod[1]=222222224;
            mod[2]=1000000007;
            for(int l=0; l<3; l++)
            {
                if(n==0)
                    continue;
                n=n-1;
                matrix a;
                a.ma[1][1]=1;
                a.ma[1][2]=a.ma[2][1]=a.ma[2][2]=0;
                matrix b;
                b.ma[1][1]=3;
                b.ma[1][2]=1;
                b.ma[2][1]=1;
                b.ma[2][2]=0;
    
                matrix ans;
                for(int i=1; i<=2; i++)
                {
                    for(int j=1; j<=2; j++)
                    {
                        if(i==j)
                            ans.ma[i][j]=1;
                        else
                            ans.ma[i][j]=0;
                    }
                }
                while(n)
                {
                    if(n&1)
                        ans=multi(ans,b,mod[l]);
                    b=multi(b,b,mod[l]);
                    n=n>>1;
                }
                n=ans.ma[1][1];
            }
            printf("%I64d
    ",n);
        }
        return 0;
    }









  • 相关阅读:
    ES monitoring
    my stackoverflow
    ES 监控
    Natural Language Processing 课程,文章,论文
    搜索引擎名著
    https://medium.com/netflix-techblog/linux-performance-analysis-in-60-000-milliseconds-accc10403c55
    MySQL 性能跟踪方法
    JAVA CAS原理深度分析 volatile,偏向锁,轻量级锁
    spark-architecture-shuffle
    Linux performance commands and tool
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/5173373.html
Copyright © 2011-2022 走看看