A Short problem
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1554 Accepted Submission(s): 566
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
Hence they prefer problems short, too. Here is a short one:
Given n (1 <= n <= 1018), 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
一眼看就会想到矩阵快速幂求模,但是仔细一看数据和g(g(g(x)))有三层就想到了这一定有循环节。
#include <stdio.h>
#define ll __int64
#define mod1 1000000007
#define mod2 222222224
#define mod3 183120
int main(){
ll a=0,b=1,c,i;
for(i=2;;i++){//求循环节
c=(b*3+a)%mod1;//mod
a=b;
b=c;
if(a == 0 && b == 1){
printf("%I64d\n",i-1);//mod2=222222224,mod3=183120
break;
}
}
return 0;
}
AC代码:
#include <stdio.h>
#include <string.h>
#define ll __int64
#define Max 2 //矩阵大小,注意能小就小
ll n;
int mod[]={183120,222222224,1000000007};
struct Matrix{
ll mm[Max][Max];
}A,I,W;
Matrix matrixmul(Matrix a,Matrix b,int mod) //矩阵乘法
{
int i,j,k;
Matrix c;
for (i = 0 ; i < 2; i++)
for (j = 0; j <2;j++){
c.mm[i][j] = 0;
for (k = 0; k <2; k++)
c.mm[i][j] += (a.mm[i][k] * b.mm[k][j])%mod;
c.mm[i][j]%=mod;
}
return c;
}
ll quickpagow(ll n,int mod){
Matrix m = A, b = I;//b是单位矩阵
while (n >= 1){
if (n & 1)
b = matrixmul(b,m,mod);
n = n >> 1;
m = matrixmul(m,m,mod);
}
b=matrixmul(W,b,mod);
return b.mm[0][0]%mod;
}
int main (){
ll i;
A.mm[0][0]=0,A.mm[0][1]=1;
A.mm[1][0]=1,A.mm[1][1]=3;
I.mm[0][0]=1,I.mm[0][1]=0;
I.mm[1][0]=0,I.mm[1][1]=1;
W.mm[0][0]=3,W.mm[0][1]=10;
W.mm[1][0]=0,W.mm[1][1]=0;
while(~scanf("%I64d",&n)){
for(i=0;i<3;i++){
if(n>=2)
n=quickpagow(n-2,mod[i]);
}
printf("%I64d\n",n);
}
return 0;
}