地斗主

地斗主

https://ac.nowcoder.com/acm/problem/19833

题意:
给你一个4 * n的矩阵,让你用1 * 2的矩阵填满,求有多少种方法?

思路:
n=1时有1种
n=2时有5种
n=3时有11种
n=4时有36种
由官方题解可知dp[i]=dp[i-1]+5d[i-2]+dp[i-3]-dp[i-4].
所以我们可以用矩阵快速幂求结果。
图片说明
为了防止产生负数,所以-1可以等价于需要模的数-1。
*
代码:**

#include <bits/stdc++.h>
typedef long long ll;

using namespace std;

ll inf=998244353;

inline int read()
{
    int x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9')
    {
        if(ch=='-')
            f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        x=(x<<1)+(x<<3)+(ch^48);
        ch=getchar();
    }
    return x*f;
}

ll s[4][4], p[4][4], a[4][4];

void che()
{
    for(int i=0;i<4;i++)
    {
        for(int j=0;j<4;j++)
        {
            p[i][j]=0;
            for(int o=0;o<4;o++)
            {
                p[i][j]=(p[i][j]+s[i][o]*a[o][j])%inf;
            }
        }
    }
    for(int i=0;i<4;i++)
    {
        for(int j=0;j<4;j++)
        {
            s[i][j]=p[i][j];
        }
    }
}

void che1()
{
    for(int i=0;i<4;i++)
    {
        for(int j=0;j<4;j++)
        {
            p[i][j]=0;
            for(int o=0;o<4;o++)
            {
                p[i][j]=(p[i][j]+a[i][o]*a[o][j])%inf;
            }
        }
    }
    for(int i=0;i<4;i++)
    {
        for(int j=0;j<4;j++)
        {
            a[i][j]=p[i][j];
        }
    }
}

void juqow(int m)
{
    while(m)
    {
        if(m&1)
        {
            che();
        }
        che1();
        m>>=1;
    }
}

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n, k;
        scanf("%d%d",&n,&k);
        inf=k;
        memset(s,0,sizeof(s));
        memset(a,0,sizeof(a));
        a[0][0]=1;
        a[0][1]=5;
        a[0][2]=1;
        a[0][3]=inf-1;
        a[1][0]=1;
        a[2][1]=1;
        a[3][2]=1;
        for(int i=0;i<=4;i++)
        {
            s[i][i]=1;
        }
        if(n==1)
        {
            printf("1\n");
        }
        else if(n==2)
        {
            printf("5\n");
        }
        else if(n==3)
        {
            printf("11\n");
        }
        else if(n==4)
        {
            printf("36\n");
        }
        else
        {
            juqow(n-4);
            printf("%lld\n",(36*s[0][0]+s[0][1]*11+s[0][2]*5+s[0][3]*1)%inf);
        }
    }
    return 0;
}
全部评论

相关推荐

11-26 22:34
已编辑
重庆邮电大学 Java
快手 客户端开发 (n+5)k*16 公积金12
牛客895077908号:佬 什么双非硕啊
点赞 评论 收藏
分享
头像
11-27 14:28
长沙理工大学
刷算法真的是提升代码能力最快的方法吗?&nbsp;刷算法真的是提升代码能力最快的方法吗?
牛牛不会牛泪:看你想提升什么,代码能力太宽泛了,是想提升算法能力还是工程能力? 工程能力做项目找实习,算法也分数据结构算法题和深度学习之类算法
点赞 评论 收藏
分享
ProMonkey2024:5个oc?厉害! 但是有一个小问题:谁问你了?😡我的意思是,谁在意?我告诉你,根本没人问你,在我们之中0人问了你,我把所有问你的人都请来 party 了,到场人数是0个人,誰问你了?WHO ASKED?谁问汝矣?誰があなたに聞きましたか?누가 물어봤어?我爬上了珠穆朗玛峰也没找到谁问你了,我刚刚潜入了世界上最大的射电望远镜也没开到那个问你的人的盒,在找到谁问你之前我连癌症的解药都发明了出来,我开了最大距离渲染也没找到谁问你了我活在这个被辐射蹂躏了多年的破碎世界的坟墓里目睹全球核战争把人类文明毁灭也没见到谁问你了(别的帖子偷来的,现学现卖😋)
点赞 评论 收藏
分享
评论
1
收藏
分享
牛客网
牛客企业服务