【JZOJ 4787】数格子

Description

这里写图片描述

Solution

很显然的矩阵乘法,我写的是16*16的,
听说有直接的递推式,只用4*4的矩阵;

复杂度: O(log(n)163)

Code

#include<cstdio>
#define fo(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
typedef long long LL;
const int N=15;
int n,mo;
LL S[N+1][N+1],a[N+1][N+1],f[N+1],t[N+1][N+1];
void pre()
{
    S[0][15]=1;
    S[1][14]=1;
    S[2][13]=1;
    S[3][15]=1,S[3][12]=1;
    S[4][11]=1;
    S[5][10]=1;
    S[6][15]=1,S[6][9]=1;
    S[7][8]=1,S[7][11]=1,S[7][14]=1;
    S[8][7]=1;
    S[9][6]=1;
    S[10][5]=1;
    S[11][4]=1,S[11][7]=1;
    S[12][15]=1,S[12][3]=1;
    S[13][2]=1,S[13][14]=1;
    S[14][1]=1,S[14][7]=1,S[14][13]=1;
    S[15][0]=1;S[15][15]=1,S[15][3]=1,S[15][6]=1,S[15][12]=1;
}
void chenf()
{
    fo(i,0,N)t[1][i]=0;
    fo(i,0,N)
        fo(j,0,N)
            (t[1][i]+=f[j]*a[j][i]%mo)%=mo;
    fo(i,0,N)f[i]=t[1][i];
}
void chen()
{
    fo(i,0,N)fo(j,0,N)t[i][j]=0;
    fo(i,0,N)
        fo(j,0,N)
            fo(k,0,N)(t[i][j]+=a[i][k]*a[k][j]%mo)%=mo;
    fo(i,0,N)fo(j,0,N)a[i][j]=t[i][j];
}
void ksm(int n)
{
    fo(i,0,N)fo(j,0,N)a[i][j]=S[i][j];
    f[N]=1;fo(i,0,N-1)f[i]=0;
    while(n)
    {
        if(n&1)chenf();
        chen();n>>=1;
    }
}
int main()
{
    pre();
    while(1)
    {
        scanf("%d%d",&n,&mo);
        if(!n)return 0;
        ksm(n);
        printf("%lld\n",f[N]);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值