题目链接
题目大意
有一个n个珠子的项链,现在要求每个素数长度的子串中的红色珠子都不少于蓝色珠子,问你长度为n的项链有多少种?
解题思路
找出递推公式F[n]=F[n-1]+F[n-3];
用矩阵快速幂求出来即可。
比赛的时候看着数那么大,没有想到用矩阵快速幂写,以为有公式或者规律可以直接出来。。。。。这个太失误了。。。。其实就是个矩阵快速幂的板子题
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
long long mod=1e9+7;
struct M
{
long long m[3][3];
};
M Mul(M a,M b)
{
M c;
memset(c.m,0,sizeof(c.m));
for(int i=0; i<3; i++)
{
for(int k=0; k<3; k++)
{
if(a.m[i][k]==0)
continue;
for(int j=0; j<3; j++)
c.m[i][j]=(c.m[i][j]+(a.m[i][k]*b.m[k][j])%mod)%mod;
}
}
return c;
}
M quick(M a,long long n)
{
M res;
memset(res.m,0,sizeof(res.m));
for(int i=0; i<3; i++)
res.m[i][i]=1;
while(n)
{
if(n&1)
res=Mul(res,a);
n>>=1;
a=Mul(a,a);
}
return res;
}
int main()
{
int T;
long long n;
scanf("%d",&T);
while(T--)
{
scanf("%lld",&n);
if(n==2)
printf("3\n");
else if(n==3)
printf("4\n");
else if(n==4)
printf("6\n");
else
{
M x;
memset(x.m,0,sizeof(x.m));
x.m[0][0]=1;x.m[0][1]=0;x.m[0][2]=1;
x.m[1][0]=1;x.m[1][1]=0;x.m[1][2]=0;
x.m[2][0]=0;x.m[2][1]=1;x.m[2][2]=0;
x=quick(x,n-4);
long long ans=((x.m[0][0]*(long long)6)%mod+(x.m[0][2]*(long long)3)%mod+(x.m[0][1]*(long long)4)%mod)%mod;
printf("%lld\n",ans);
}
}
return 0;
}