Gym - 102302H
A sequence of numbers A is said to be logarithm concave if, and only if, for every 2 ≤ i ≤ n - 1, ai - 1 * ai + 1 ≤ ai2.
For example the sequence A = (1, 2, 3) is logarithm concave. The sequence A = (2, 2, 3) is not logarithm concave.
In this problem, you will have to answer what is the number of log concave sequences which contain only the numbers 0, 1 or 2, with N elements.
As this number could be very large, print the answer mod 109 + 7.
Input
The input consists of a single integer N (3 ≤ N ≤ 1018) indicating the size of the log concave sequence.
Output
One integer with the number of log concave sequences with size N that contains only the numbers 0, 1 or 2.
Example
Input
3
Output
20
两个数组合有九种方式:00,01,02,10,11,12,20,21,22,分别为dp[1~9] ;
则根据每一个状态可以由前一个状态添加一个数(0,1,2)取后两位,转化而来,可以得到
dp[1] = dp[1] + dp[4] + dp[7]
dp[2] = dp[1]
dp[3] = dp[1]
dp[4] = dp[2] + dp[5] + dp[8]
dp[5] = dp[2] + dp[5]
dp[6] = dp[2]
dp[7] = dp[3] + dp[6] + dp[9]
dp[8] = dp[3] + dp[6] + dp[9]
dp[9] = dp[3] + dp[6] + dp[9]
转化为矩阵
dp
1 2 3 4 5 6 7 8 9
1 1 1 0 0 0 0 0 0
0 0 0 1 1 1 0 0 0
0 0 0 0 0 0 1 1 1
1 0 0 0 0 0 0 0 0
0 0 0 1 1 0 0 0 0
0 0 0 0 0 0 1 1 1
1 0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0
0 0 0 0 0 0 1 1 1
此矩阵的每个单位的和为n ==3式的答案
求矩阵的n-3次幂即为答案
#include
using namespace std;
const int maxn= 1e9+7;
struct node
{
long long mar[10][10];
};
node a,b;
node mul(node a, node b)
{
node c;
memset(c.mar,0,sizeof(c.mar));
for(int i = 0; i < 9; i ++)
{
for(int j = 0; j < 9; j ++)
{
if(a.mar[j][i]!= 0)
{
for(int k = 0; k < 9; k ++)
{
c.mar[j][k] += a.mar[j][i]*b.mar[i][k];
c.mar[j][k] %= maxn;
}
}
}
}
return c;
}
node quick_mul(node a, long long num)
{
node ans;
memset(ans.mar,0,sizeof(ans.mar));
for(int i = 0; i < 9; i ++)
{
ans.mar[i][i] = 1;
}
while(num)
{
if(num&1)
{
ans = mul(ans,a);
}
a = mul(a,a);
num >>= 1;
}
return ans;
}
int main()
{
long long i,j,k,m,n,ans;
scanf("%lld",&n);
memset(a.mar,0,sizeof(a.mar));
for(i = 0; i <= 2; i ++)//求得初始矩阵
{
for(j = 0; j <= 2; j ++)
{
for(k = 0; k <= 2; k ++)
{
if(i*i >= k*j)
a.mar[k*3+i][i*3+j] =1;
}
}
}
for(i = 0; i < 9; i ++)
{
for(j = 0; j < 9; j ++)
{
if(a.mar[i][j])
printf("1 ");
else
printf("0 ");
}
printf("\n");
}
b = quick_mul(a,n-2);
ans = 0;
for(i = 0; i < 9; i ++)
{
for(j = 0; j < 9; j ++)
{
ans = (ans+b.mar[i][j])%maxn;
}
}
printf("%lld\n",ans);
return 0;
}