思路:先用矩阵快速幂,求出要构造矩阵的大小,接下来就是怎么构造的了,不太会参考了别人的博客,这个构造的就很清晰了。
参考链接
求出来计算出L=S(n)%m之后,构造题目中要求的矩阵,找规律后发现,可以构造成以下最简单的形式
当L=0或者L为奇数时为No,L为偶数时Yes,例如L=6时
0 1 1 1 1 1
-1 0 1 1 1 1
-1 -1 0 1 1 1
-1 -1 -1 1 1 1
-1 -1 -1 -1 1 1
-1 -1 -1 -1 -1 1
对角线前一半为0,后一半为1,上三角为1,下三角为-1
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
ll mod;
struct matrix{
ll x[3][3];
};
matrix multi(matrix a,matrix b){
matrix temp;
memset(temp.x,0,sizeof(temp.x));
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
for(int k=0;k<3;k++)
{
temp.x[i][j]+=a.x[i][k]*b.x[k][j];
temp.x[i][j]%=mod;
//if(temp.x[i][j]<0) temp.x[i][j]=(temp.x[i][j]+mod)%mod;
}
return temp;
}
matrix quick_multi(matrix a,ll n)//矩阵快速幂
{
matrix temp=a;
n--;
while(n){
if(n&1)
temp=multi(temp,a);
a=multi(a,a);
n>>=1;
}
return temp;
}
int main()
{
int t;
ll n,kcase=0;
scanf("%d",&t);
while(t--)
{
scanf("%lld%lld",&n,&mod);
printf("Case %lld: ",++kcase);
matrix A,B;
ll ans;
if(n==2) ans=2%mod;
else
{
memset(A.x,0,sizeof(A.x));
memset(B.x,0,sizeof(B.x));
A.x[0][0]=A.x[0][1]=A.x[0][2]=1;
A.x[1][1]=A.x[1][2]=1;
A.x[2][1]=1;
B.x[0][0]=2;B.x[1][0]=B.x[2][0]=1;
A=quick_multi(A,n-2);
B=multi(A,B);
ans=B.x[0][0]%mod;
}
if(ans%2==0&&(ans!=0))
{
printf("Yes\n");
//规律不会找看大佬写的六啊
int s[210][210];
for(int i=0;i<ans;i++)
{
if(i<ans/2) s[i][i]=0;
else s[i][i]=1;
for(int j=i+1;j<ans;j++)
s[i][j]=1;
for(int j=0;j<i;j++)
s[i][j]=-1;
}
for(int i=0;i<ans;i++)
{
for(int j=0;j<ans;j++)
j==0?printf("%d",s[i][j]):printf(" %d",s[i][j]);
printf("\n");
}
}
else
printf("No\n");
}
return 0;
}