Description
问只由 R,B,W,Y 组成的长度介于 [L,R] 的字符串且满足以下四个条件的字符串数量
1 .相邻两个字符不同
3
.不能出现连续三个字符是
4 .两个字符串互为反序视做同一个
Input
输入两个整数
Output
输出长度介于 [L,R] 之间且满足条件的字符串数量,结果模 109+7
Sample Input
3 4
Sample Output
23
Solution
dp[i][c]
表示长度为
i
且第
则有转移方程
dp[i][R]=dp[i−1][W]+dp[i−1][Y]−dp[i−2][B]
dp[i][B]=dp[i−1][W]+dp[i−1][Y]−dp[i−2][R]
dp[i][W]=dp[i−1][R]+dp[i−1][B]
dp[i][Y]=dp[i−1][R]+dp[i−1][B]
记 S[i]=∑j=1i(dp[i][R]+dp[i][B]+dp[i][W]+dp[i][Y])
则有
做矩阵快速幂求出 S[n] 即得到所有长度不超过 n 的字符串数量,但是注意到反序视作一种,但直接对
Code
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<ctime>
using namespace std;
typedef long long ll;
typedef pair<int,int>P;
const int INF=0x3f3f3f3f,maxn=100001;
typedef ll M[9][9];
const int p=1e9+7,inv2=500000004;
void Mul(M &A,M B)
{
M C;
for(int i=0;i<9;i++)
for(int j=0;j<9;j++)
{
C[i][j]=0;
for(int k=0;k<9;k++)C[i][j]+=A[i][k]*B[k][j]%p;
}
for(int i=0;i<9;i++)
for(int j=0;j<9;j++)
A[i][j]=C[i][j]%p;
}
void Pow(M &A,ll k)
{
M B;
for(int i=0;i<9;i++)
for(int j=0;j<9;j++)
B[i][j]=(i==j);
while(k)
{
if(k&1)Mul(B,A);
Mul(A,A);
k>>=1;
}
for(int i=0;i<9;i++)
for(int j=0;j<9;j++)
A[i][j]=B[i][j];
}
M A={
{0,0,1,1,0,p-1,0,0,0},
{0,0,1,1,p-1,0,0,0,0},
{1,1,0,0,0,0,0,0,0},
{1,1,0,0,0,0,0,0,0},
{1,0,0,0,0,0,0,0,0},
{0,1,0,0,0,0,0,0,0},
{0,0,1,0,0,0,0,0,0},
{0,0,0,1,0,0,0,0,0},
{1,1,1,1,0,0,0,0,1}};
//RBWY
int Solve(ll n)
{
M B;
for(int i=0;i<9;i++)
for(int j=0;j<9;j++)
B[i][j]=A[i][j];
Pow(B,n);
int ans=0;
for(int i=0;i<4;i++)ans=(ans+B[8][i])%p;
for(int i=0;i<9;i++)
for(int j=0;j<9;j++)
B[i][j]=A[i][j];
Pow(B,(n+1)/2);
for(int i=0;i<4;i++)ans=(ans+B[8][i]+p)%p;
return (ll)ans*inv2%p;
}
int main()
{
ll L,R;
while(~scanf("%I64d%I64d",&L,&R))
{
int ans=(Solve(R)-Solve(L-1)+p)%p;
printf("%d\n",ans);
}
return 0;
}