题意:
F(n)为斐波那契数列,S(n)为其前缀和,给你n,m,求S(n)%m的值作为矩阵边长,构造矩阵行和列的值都不相等
思路:
= =、强行把两道题凑成一道题;
求斐波那契前缀和–矩阵快速幂;(具体构造矩阵看代码)
构造方法:
四个角放好,然后水平,竖直放...
具体看代码(懒得写…)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<stack>
#include<queue>
#include<deque>
#include<map>
#include<algorithm>
using namespace std;
typedef long long LL;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF=0x3f3f3f3f;
//const int mod = 1e9;
const int N = 210;
struct Mat{
int p[4][4];
};
int n,mod;
Mat mul(Mat a,Mat b)
{
Mat c;
memset(c.p,0,sizeof(c.p));
for(int i = 0; i < 3; i++)
for(int j = 0; j < 3; j++)
for(int k = 0; k < 3; k++)
c.p[i][j] = (c.p[i][j]+a.p[i][k]*b.p[k][j]%mod+mod)%mod;
return c;
}
Mat quick_mi(Mat a,int nn)
{
Mat b;
memset(b.p, 0, sizeof(b.p));
for(int i = 0; i < 3; i++)
b.p[i][i] = 1;
while(nn)
{
if(nn&1) b = mul(b,a);
a = mul(a,a);
nn>>=1;
}
return b;
}
int ma[N][N];
void solve(int m)
{
if(!m || m&1){
puts("No");
return ;
}
int l = 1;
int r = m;
ma[l][l] = -1; ma[l][r] = 1; ma[r][l] = 0; ma[r][r] = 1;
l++;
r--;
while(l < r)
{
for(int i = l; i <= r; i++)
{
ma[l-1][i] = -1;
ma[r+1][i] = 1;
ma[i][l-1] = -1;
ma[i][r+1] = 1;
}
ma[l][l] = -1; ma[l][r] = 1; ma[r][l] = 0; ma[r][r] = 1;
l++;
r--;
}
puts("Yes");
for(int i = 1; i <= m; i++){
for(int j = 1; j <= m; j++){
if(j!=1)
printf(" ");
printf("%d",ma[i][j]);
}
puts("");
}
}
int main()
{
int T;
scanf("%d",&T);
int res;
for(int cas = 1; cas <= T; cas++)
{
scanf("%d%d",&n,&mod);
if(n == 2)
res = 2%mod;
else
{
Mat a,b;
memset(a.p,0,sizeof(a.p));
a.p[0][0] = a.p[1][0] = a.p[2][0] = a.p[0][2] = a.p[2][2] = 1;
a.p[2][1] = -1;
a = quick_mi(a,n-2);
memset(b.p,0,sizeof(b.p));
b.p[0][0] = 2, b.p[1][0] = 1; b.p[2][0] = 2;
a = mul(a,b);
res = a.p[0][0];
}
printf("Case %d: ",cas);
solve(res);
}
return 0;
}