(矩陣快速冪)CF102302H. Log Concave Sequences

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,就可以用矩陣快速冪。
計算矩陣:
[100100100100000000100000000010010010010010000010000000001001001001001001001001001]N3\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}
最後計算
i=1,j=19mat[i][j]\sum_{i=1,j=1}^9mat[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;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章