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
2012 ACM/ICPC Asia Regional Chengdu Online  

 

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;
}

 

    原文作者:算法小白
    原文地址: https://www.cnblogs.com/kuangbin/archive/2012/09/17/2688852.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞