题意:
中文题不解释
注意是n位数!
思路:
中文在群里问了大神们,终于领悟到这种递推的精华
对于给定的n都会包含有四种状态
0、7和9的个数都是奇数
1、7是奇数,9是偶数
2、7是偶数,9是奇数
3、7是偶数,9是偶数
显然状态3是我们要状态,但是他们之间是可以互相转移的
所以对于每次添加一个空位放数字,建立转移矩阵
| 3 1 1 0 |
| 1 3 0 1 |
| 1 0 3 1 |
| 0 1 1 3 |
初始状态为 (0,0,0,1)
然后就是n次方了~利用矩阵快速幂
最后ans.mat[0][3]就是答案了
代码:
#include"cstdlib"
#include"cstdio"
#include"cstring"
#include"cmath"
#include"queue"
#include"algorithm"
#include"iostream"
using namespace std;
__int64 mod=1000000007;
struct matrix
{
__int64 mat[5][5];
};
matrix matmul(matrix a,matrix b,int n,int m)
{
int i,j,k;
matrix c;
memset(c.mat,0,sizeof(c.mat));
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
for(k=0;k<n;k++)
{
c.mat[i][j]+=a.mat[i][k]*b.mat[k][j];
c.mat[i][j]%=m;
}
}
}
return c;
}
matrix matpow(matrix a,__int64 k,int n,int m)
{
matrix b;
int i;
memset(b.mat,0,sizeof(b.mat));
for(i=0;i<n;i++) b.mat[i][i]=1;
while(k)
{
if(k&1) b=matmul(a,b,n,m);
a=matmul(a,a,n,m);
k>>=1;
}
return b;
}
int main()
{
int t;
cin>>t;
while(t--)
{
matrix a,b,ans;
memset(a.mat,0,sizeof(a.mat));
memset(b.mat,0,sizeof(b.mat));
a.mat[0][3]=1;
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
if(i==j) b.mat[i][j]=3;
else if(i+j==3) b.mat[i][j]=0;
else b.mat[i][j]=1;
}
}
__int64 k;
scanf("%I64d",&k);
ans=matmul(a,matpow(b,k,4,mod),4,mod);
__int64 sum=0;
printf("%I64d\n",ans.mat[0][3]);
}
return 0;
}