Construct a Matrix FZU - 1911

Construct a Matrix FZU - 1911

思路:先用矩陣快速冪,求出要構造矩陣的大小,接下來就是怎麼構造的了,不太會參考了別人的博客,這個構造的就很清晰了。
參考鏈接
求出來計算出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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章