CF102302H. Log Concave Sequences
题意&思路:
有n位数,每位只包含0,1,2,要求对于每个位置,ai2>=ai-1*ai+1。求这样的数有多少。
对于答案的3,我们可以列举:
000 001 002 010 011 012 020 021 022
100 101× 102× 110 111 112× 120 121 122
200 201× 202× 210 211× 212× 220 221 222
(×为不满足)
那么我们在寻找第四位的时候只需要在三位合法的情况下,寻找第四位能够使前三位合法的解。这样我们就将问题变成了dp。由后两位的值,决定第三位的个数。dp[i][j][k]表示第i位,j,k表示后两位的值。
可得:
dp[i][0][0]=dp[i-1][0][0]+dp[i-1][1][0]+dp[i-1][2][0]
dp[i][0][1]=dp[i-1][0][0]
dp[i][0][2]=dp[i-1][0][0]
dp[i][1][0]=dp[i-1][0][1]+dp[i-1][1][1]+dp[i-1][2][1]
dp[i][1][1]=dp[i-1][0][1]+dp[i-1][1][1]
dp[i]1][2]=dp[i-1][0][1]
dp[i][2][0]=dp[i-1][0][2]+dp[i-1][1][2]+dp[i-1][2][2]
dp[i][2][1]=dp[i-1][0][2]+dp[i-1][1][2]+dp[i-1][2][2]
dp[i][2][2]=dp[i-1][0][2]+dp[i-1][1][2]+dp[i-1][2][2]
由于N高达1018,递推肯定T,就可以用矩阵快速幂。
计算矩阵:
[
1
0
0
1
0
0
1
0
0
1
0
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
1
0
0
1
0
0
1
0
0
1
0
0
1
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
1
0
0
1
0
0
1
0
0
1
0
0
1
0
0
1
0
0
1
0
0
1
0
0
1
]
N
−
3
\left[ \begin {matrix} 1&0&0&1&0&0&1&0&0\\ 1&0&0&0&0&0&0&0&0\\ 1&0&0&0&0&0&0&0&0\\ 0&1&0&0&1&0&0&1&0\\ 0&1&0&0&1&0&0&0&0\\ 0&1&0&0&0&0&0&0&0\\ 0&0&1&0&0&1&0&0&1\\ 0&0&1&0&0&1&0&0&1\\ 0&0&1&0&0&1&0&0&1\\ \end{matrix} \right ]^{N-3}
⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎡111000000000111000000000111100000000000110000000000111100000000000100000000000111⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎤N−3
最后计算
∑
i
=
1
,
j
=
1
9
m
a
t
[
i
]
[
j
]
\sum_{i=1,j=1}^9mat[i][j]
∑i=1,j=19mat[i][j]
代码:
#include<bits/stdc++.h>
#define pii pair<int,int>
#define ll long long
#define cl(x,y) memset(x,y,sizeof(x))
#define ct cerr<<"Time elapsed:"<<1.0*clock()/CLOCKS_PER_SEC<<"s.\n";
const int N=1e6+10;
const int mod=1e9+7;
const int maxn=0x3f3f3f3f;
const int minn=0xc0c0c0c0;
const int inf=99999999;
using namespace std;
struct mat
{
ll maze[10][10];
mat()
{
cl(maze,0);
}
};
mat mul(mat a,mat b)
{
mat c;
int i,j,k;
for(i=1;i<=9;i++)
for(j=1;j<=9;j++)
for(k=1;k<=9;k++)
c.maze[i][j]=(c.maze[i][j]+a.maze[i][k]*b.maze[k][j])%mod;
return c;
}
mat matpow(mat a,ll n)
{
mat b;
int i,j;
for(i=1;i<=9;i++)
for(j=1;j<=9;j++)
b.maze[i][j]=i==j?1:0;
while(n)
{
if(n&1)
b=mul(b,a);
a=mul(a,a);
n>>=1;
}
return b;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
ll n,i,j;
cin>>n;
mat a;
a.maze[1][1]=1;a.maze[1][2]=0;a.maze[1][3]=0;a.maze[1][4]=1;a.maze[1][5]=0;a.maze[1][6]=0;a.maze[1][7]=1;a.maze[1][8]=0;a.maze[1][9]=0;
a.maze[2][1]=1;a.maze[2][2]=0;a.maze[2][3]=0;a.maze[2][4]=0;a.maze[2][5]=0;a.maze[2][6]=0;a.maze[2][7]=0;a.maze[2][8]=0;a.maze[2][9]=0;
a.maze[3][1]=1;a.maze[3][2]=0;a.maze[3][3]=0;a.maze[3][4]=0;a.maze[3][5]=0;a.maze[3][6]=0;a.maze[3][7]=0;a.maze[3][8]=0;a.maze[3][9]=0;
a.maze[4][1]=0;a.maze[4][2]=1;a.maze[4][3]=0;a.maze[4][4]=0;a.maze[4][5]=1;a.maze[4][6]=0;a.maze[4][7]=0;a.maze[4][8]=1;a.maze[4][9]=0;
a.maze[5][1]=0;a.maze[5][2]=1;a.maze[5][3]=0;a.maze[5][4]=0;a.maze[5][5]=1;a.maze[5][6]=0;a.maze[5][7]=0;a.maze[5][8]=0;a.maze[5][9]=0;
a.maze[6][1]=0;a.maze[6][2]=1;a.maze[6][3]=0;a.maze[6][4]=0;a.maze[6][5]=0;a.maze[6][6]=0;a.maze[6][7]=0;a.maze[6][8]=0;a.maze[6][9]=0;
a.maze[7][1]=0;a.maze[7][2]=0;a.maze[7][3]=1;a.maze[7][4]=0;a.maze[7][5]=0;a.maze[7][6]=1;a.maze[7][7]=0;a.maze[7][8]=0;a.maze[7][9]=1;
a.maze[8][1]=0;a.maze[8][2]=0;a.maze[8][3]=1;a.maze[8][4]=0;a.maze[8][5]=0;a.maze[8][6]=1;a.maze[8][7]=0;a.maze[8][8]=0;a.maze[8][9]=1;
a.maze[9][1]=0;a.maze[9][2]=0;a.maze[9][3]=1;a.maze[9][4]=0;a.maze[9][5]=0;a.maze[9][6]=1;a.maze[9][7]=0;a.maze[9][8]=0;a.maze[9][9]=1;
a=matpow(a,n-2);
ll res=0;
for(i=1;i<=9;i++)
for(j=1;j<=9;j++)
res=(res+a.maze[i][j])%mod;
cout<<res<<endl;
return 0;
}