HDU 4291 A Short problem 第37届ACM/ICPC 成都赛区网络赛1004题 (找规律,取模求循环节)

A Short problem

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


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
 

 

Source
 

 

Recommend
liuyiding
 
 
这么水的题目比赛时竟然没有做出来。。。
惭愧啊!!!!
其实只要是取模都可以找到循环节的。
第一次是MOD=1000000007 找出循环节是222222224
第二次是MOD=222222224,找出循环节183120
找循环节暴力找就可以了,矩阵乘法找循环节更加慢。
附上找循环节程序:
View Code
#include<stdio.h>



const long long MOD=222222224;//第一次是MOD=1000000007 找出循环节是222222224

//第二次是MOD=222222224,找出循环节183120

int main()

{

    long long a,b;

    a=1;

    b=3;

    for(int i=1;;i++)

    {

        if(a==0&&b==1)

        {

            printf("%d\n",i);

            break;

        }

        long long c=3*b+a;

        c%=MOD;

        a=b;

        b=c;

    }

    return 0;

}

 

下面是程序。

//1004

#include<stdio.h>

#include<iostream>

#include<map>

#include<set>

#include<algorithm>

#include<string.h>

#include<stdlib.h>

using namespace std;

const long long MOD=1000000007;

const long long MOD2=222222224;

const long long MOD3=183120;

const int MAXN=10;

struct Matrix

{

    long long mat[MAXN][MAXN];

    int n,m;

};

Matrix mul(Matrix a,Matrix b,long long m)

{

    Matrix ret;

    ret.n=a.n;

    ret.m=b.m;

    for(int i=0;i<a.n;i++)

       for(int j=0;j<b.m;j++)

       {

           ret.mat[i][j]=0;

           for(int k=0;k<a.m;k++)

           {

               ret.mat[i][j]+=(a.mat[i][k]*b.mat[k][j]%m);

               ret.mat[i][j]%=m;

           }

       }

    return ret;

}

Matrix pow(Matrix a,long long n,long long m)

{

    if(n==1)return a;

    Matrix ret=a;

    Matrix temp=a;

    for(int i=0;i<a.n;i++)

      for(int j=0;j<a.n;j++)

      {

          if(i==j)ret.mat[i][j]=1;

          else ret.mat[i][j]=0;

      }

    while(n)

    {

        if(n&1)ret=mul(ret,temp,m);

        temp=mul(temp,temp,m);

        n>>=1;

    }

    return ret;

}



int main()

{

    //freopen("D.in","r",stdin);

   // freopen("D.out","w",stdout);

    Matrix A;

    A.n=A.m=2;

    A.mat[0][0]=3;

    A.mat[0][1]=1;

    A.mat[1][0]=1;

    A.mat[1][1]=0;

    Matrix f0;

    f0.n=2;

    f0.m=1;

    f0.mat[0][0]=1;

    f0.mat[1][0]=0;





    long long n;

    Matrix tmp;

    Matrix temp;

    while(scanf("%I64d\n",&n)!=EOF)

    {

        temp=pow(A,n,MOD3);

        tmp=mul(temp,f0,MOD3);

        long long tt=tmp.mat[1][0];



        temp=pow(A,tt,MOD2);

        tmp=mul(temp,f0,MOD2);

        tt=tmp.mat[1][0];



        temp=pow(A,tt,MOD);

        tmp=mul(temp,f0,MOD);

        tt=tmp.mat[1][0];



        printf("%I64d\n",tt);

    }



    return 0;

}

 

你可能感兴趣的:(ICPC)