A Short problem
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 591 Accepted Submission(s): 230
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
Recommend
liuyiding
g(g(g(n)))对1000000007求余得到的循环节222222224,那么g(g(n))对222222224求余后再计算g(g(g(n)))是相等的,以此类推,求g(g(g(n)))就是求g(g(g(n)%183120)%222222224)%1000000007.
先本地暴力求出分别对1000000007取余的循环节为222222224,然后再对222222224暴力求出循环节为183120,最后分别对三种求余进行矩阵连乘计算
循环节代码:
#include <iostream>
#include <stdio.h>
using namespace std;
const long long mod=1000000007;//求出循环节为222222224,然后改为222222224再求一次
int main()
{
long long g1,g2,s;
long long i=1;
g1=0;g2=1;
for(;;i++)
{
long long s=(3*g2+g1)%mod;
g1=g2;g2=s;
if(g1==0&&g2==1) break;
}
printf("%lld\n",i);
system("pause");
return 0;
}
AC代码:
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstdio>
using namespace std;
long long Mod;
const int MAX = 2;
typedef struct
{
long long m[MAX][MAX];
} Matrix;
Matrix P =
{
3,1,
1,0,
};
Matrix I =
{
1,0,
0,1,
};
Matrix matrixmul(Matrix a,Matrix b)
{
int i,j,k;
Matrix c;
for (i = 0 ; i < MAX; i++)
for (j = 0; j < MAX; j++)
{
c.m[i][j] = 0;
for (k = 0; k < MAX; k++)
c.m[i][j] += (a.m[i][k]%Mod) * (b.m[k][j]%Mod);
c.m[i][j] %= Mod;
}
return c;
}
Matrix quickpow(long long n)
{
Matrix m = P, b = I;
while (n >= 1)
{
if (n & 1)
b = matrixmul(b,m);
n = n >> 1;
m = matrixmul(m,m);
}
return b;
}
int main()
{
long long n;
while(cin>>n)
{
if(n<=1)
{
cout<<n<<endl;
continue;
}
Mod=183120;
Matrix C;
C=quickpow(n-1);
n=C.m[0][0];
if(n<=1)
{
cout<<n<<endl;
continue;
}
Mod=222222224;
Matrix C1;
C1=quickpow(n-1);
n=C1.m[0][0];
if(n<=1)
{
cout<<n<<endl;
continue;
}
Mod=1000000007;
Matrix C2;
C2=quickpow(n-1);
n=C2.m[0][0]%Mod;
cout<<n<<endl;
}
return 0;
}