时间限制:C/C++ 2秒,其他语言4秒
空间限制:C/C++ 131072K,其他语言262144K
64bit IO Format: %lld
空间限制:C/C++ 131072K,其他语言262144K
64bit IO Format: %lld
题目描述
JYM和XJ转眼就从小学上了高中。在学习递推的时候,JYM在纸上随手写了一个递推关系式:a
n=2*a
n-1,a
0=0。写完这个递推式,JYM拿给XJ看,XJ觉得太过简单,于是大笔一挥,在等式右边又加了一个式子,变成了这样:a
n=2*a
n-1+n
2。JYM看到这个式子,想要算几个项来看看,可是一算就发现这个数据量太大了,你能帮他解决这个问题吗?
输入描述:
输入数据有多组(不超过100组数据),每组数据包含一个整数N<=1018
输出描述:
一个整数X,表示递推式第n项的值。由于数字太大,因此结果对于1000000009取模后输出。
示例1
输入
0 1 2 3
输出
0 1 6 21
#include<bits/stdc++.h>
using namespace std;
const long long MOD=1000000009;
struct lenka
{
long long a[4][4];
};
lenka cla(const lenka& a,const lenka& b)
{
lenka c;
memset(c.a,0,sizeof c.a);
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
for(int k=0;k<4;k++)
{
c.a[i][j]+=a.a[i][k]*b.a[k][j];
c.a[i][j]%=MOD;
}
}
}
return c;
}
long long POW(long long n)
{
lenka res,a;
memset(res.a,0,sizeof res.a);
memset(a.a,0,sizeof a.a);
for(int i=0;i<4;i++)res.a[i][i]=1;
a.a[0][0]=2,a.a[0][1]=0,a.a[0][2]=0,a.a[0][3]=0;
a.a[1][0]=1,a.a[1][1]=1,a.a[1][2]=0,a.a[1][3]=0;
a.a[2][0]=2,a.a[2][1]=2,a.a[2][2]=1,a.a[2][3]=0;
a.a[3][0]=1,a.a[3][1]=1,a.a[3][2]=1,a.a[3][3]=1;
while(n)
{
if(n&1)res=cla(res,a);
a=cla(a,a);
n/=2;
}
return ((res.a[0][0]+res.a[1][0])%MOD+(res.a[2][0]+res.a[3][0])%MOD)%MOD;
}
int main()
{
long long n;
while(scanf("%lld",&n)!=EOF)
{
if(n==0)puts("0");
else printf("%lld\n",POW(n-1));
}
return 0;
}