NKOJ 简单的计算 (矩阵KSM)

时间限制 : - MS   空间限制 : - KB
评测说明 : 时限1s,空限128m
问题描述

  给你三个整数 N, x, 和 M, 计算下列式子:

 

注意构造矩阵时的行列

code:

//
#include<bits/stdc++.h>
using namespace std;
#define ll long long 
typedef ll xwz[55][55];
ll n,x,m;

xwz aa;
xwz c;
xwz res;
xwz rres;
ll  ddd[55];
void cheng(xwz ccc,xwz rr)
{
    memset(rres,0,sizeof(rres));
    for(int i=1;i<=x+2;i++)
    for(int j=1;j<=x+2;j++)
    for(int k=1;k<=x+2;k++)
    {
        rres[i][j]=(rres[i][j]%m+((ccc[i][k]%m)*(rr[k][j]%m)))%m;
    }
    memcpy(ccc,rres,sizeof(rres));
}
void ksm(xwz cc)
{
    ll b=n;
    memset(res,0,sizeof(res));
    for(int i=1;i<=x+2;i++) res[i][i]=1;
    while(b)
    {
        if(b&1) cheng(res,cc);
        b>>=1;
        cheng(cc,cc);
    }
    memcpy(cc,res,sizeof(res));
}
int main()
{
    cin>>n>>x>>m;
    for(int i=0;i<=53;i++)
    {
        c[i][0]=1;
    }
    for(int i=1;i<=x+2;i++)
        for(int j=1;j<=i;j++)
        {
            c[i][j]=c[i-1][j]%m+c[i-1][j-1]%m;
        }
    for(int j=1;j<=x+1;j++)
        for(int i=1;i<=j;i++)
        {
                aa[i][j]=(c[j-1][i-1]*x)%m;
        }
    aa[x+1][x+2]=aa[x+2][x+2]=1;
    ksm(aa);
    for(int i=1;i<=x+1;i++)
    {
        ddd[i]=x;
    }
    ll ans=0;
    for(int j=1;j<=x+2;j++)
    {
        ans+=ddd[j]*aa[j][x+2]%m;
    }
//    for(int j=1;j<=x+1;j++)
//    {
//        ans+=ddd[j]*aa[j][x+1]%m;
//    }
    printf("%lld",ans%m);
}

 

 

posted @ 2019-08-04 11:30  ALEZ  阅读(526)  评论(0编辑  收藏  举报