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
从最外层找循环节
最外层:即当mod为1000000007时
暴力找出循环节为2222222224
即g(222222225%222222224)%1000000007=g(1)%1000000007;
即g(x)%1000000007=g(x%222222224)%1000000007;
第二层:即当mod为222222224时
暴力找出循环节为183120
即g(183121%183120)%222222224=g(1)%222222224;
即g(x)%222222224=g(x%183120)%222222224;
第三层:即当mod为183120时
暴力找出循环节为240;
即g(241%240)%183120=g(1)%183120;
即g(x)%183120=g(x%240)%183120;
最后:g(g(g(n)))%1000000007=g(g(g(n)%222222224)%1000000007=g(g(g(n)%183120)%222222224)%1000000007
=g(g(g(n%240)%183120)%222222224)%1000000007;
暴力跑循环节代码:
#include <bits/stdc++.h>
using namespace std;
long long get(long long mod)
{
long long u=1,v=3;
long long ans;
for(int i=1;i<=999999999;i++)
{
if(u==0&&v==1)
{
ans=i;
break;
}
long long t=u;
u=v;
v=(t+3*v)%mod;
}
return ans;
}
int main()
{
int mod;
while(cin >> mod)
{
cout << get(mod) << endl;
}
return 0;
}
AC代码:
#include <bits/stdc++.h>
using namespace std;
struct node{
long long a[2][2];
}ans,k,t;
long long mod1=183120;
long long mod2=222222224;
long long mod3=1000000007;
node mult(node x,node y,long long mod)
{
node now;
now.a[0][0]=(x.a[0][0]*y.a[0][0]%mod+x.a[0][1]*y.a[1][0]%mod)%mod;
now.a[0][1]=(x.a[0][0]*y.a[0][1]%mod+x.a[0][1]*y.a[1][1]%mod)%mod;
now.a[1][0]=(x.a[1][0]*y.a[0][0]%mod+x.a[1][1]*y.a[1][0]%mod)%mod;
now.a[1][1]=(x.a[1][0]*y.a[0][1]%mod+x.a[1][1]*y.a[1][1]%mod)%mod;
return now;
}
long long quick_pow(long long n,long long mod)
{
n--;
ans.a[0][0]=1;
ans.a[1][1]=1;
ans.a[0][1]=0;
ans.a[1][0]=0;
k=t;
while(n)
{
if(n&1)
{
ans=mult(ans,k,mod);
}
k=mult(k,k,mod);
n>>=1;
}
return ans.a[0][0]%mod;
}
int main()
{
long long n;
t.a[0][0]=3;
t.a[0][1]=1;
t.a[1][0]=1;
t.a[1][1]=0;
while(cin >> n)
{
n%=240;
if(!n)
{
cout << 0 << endl;
continue;
}
n=quick_pow(n,mod1);
n=quick_pow(n,mod2);
n=quick_pow(n,mod3);
cout << n << endl;
}
return 0;
}