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
Hence they prefer problems short, too. Here is a short one:
Given n (1 <= n <= 10 18), You should solve for
where
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).
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
这么水的题目比赛时竟然没有做出来。。。
惭愧啊!!!!
其实只要是取模都可以找到循环节的。
第一次是MOD=1000000007 找出循环节是222222224
第二次是MOD=222222224,找出循环节183120
第二次是MOD=222222224,找出循环节183120
找循环节暴力找就可以了,矩阵乘法找循环节更加慢。
附上找循环节程序:
#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;
}