矩阵快速幂——HDU5667

Posted helman

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了矩阵快速幂——HDU5667相关的知识,希望对你有一定的参考价值。

题目链接

分析全在纸上,博客上懒得写

我是个蒟蒻,只有源代码

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
typedef long long LL;
const int maxn=107;
LL mod;
struct mat
    LL m[maxn][maxn];
    int x,y;///x是行数y是列数
unit;
void init_unit()
    memset(unit.m,0,sizeof(unit.m));
    for(int i=0;i<maxn;i++)
        unit.m[i][i]=1;

void show(mat a)
    for(int i=1;i<=a.x;i++)
        for(int j=1;j<=a.y;j++)
            printf("%d ",a.m[i][j]);
        printf("\n");
    

mat mat_mul(mat a,mat b)
    mat c;
    c.x=a.x,c.y=b.y;
    memset(c.m,0,sizeof(c.m));
    for(int i=1;i<=c.x;i++)
    for(int j=1;j<=c.y;j++)
        for(int k=1;k<=a.y;k++)
            c.m[i][j]+=(a.m[i][k]*b.m[k][j])%(mod-1);
            c.m[i][j]%=mod-1;
        
    
    return c;

mat mat_QuickPow(mat a,LL b)
    mat ans=unit;
    ans.x=a.x,ans.y=a.y;
    while(b)
        if(b&1)
            ans=mat_mul(ans,a);
        a=mat_mul(a,a);
        b>>=1;
    
    return ans;

LL QuickPow(LL a,LL b)
    LL ans=1;
    while(b)
        if(b&1)ans=(ans*a)%mod;
        a=(a*a)%mod;
        b>>=1;
    
    return ans;

int t;
LL n,x,y,z;
int main()
    scanf("%d",&t);
    init_unit();
    while(t--)
        scanf("%I64d%I64d%I64d%I64d%I64d",&n,&x,&y,&z,&mod);
        mat a;
        a.x=a.y=3;
        a.m[1][1]=1,a.m[1][2]=y,a.m[1][3]=0;
        a.m[2][1]=0,a.m[2][2]=z,a.m[2][3]=1;
        a.m[3][1]=0,a.m[3][2]=1,a.m[3][3]=0;
        if(n==1)
            printf("1\n");
            continue;
        
        if(n==2)
            printf("%I64d\n",QuickPow(x,y));
            continue;
        
        a=mat_QuickPow(a,n-2);
        LL t=(a.m[1][2]+a.m[2][2]*y);
        printf("%I64d\n",QuickPow(x,t));
    
    return 0;

 

以上是关于矩阵快速幂——HDU5667的主要内容,如果未能解决你的问题,请参考以下文章

求幂大法,矩阵快速幂,快速幂模板题--hdu4549

一些特殊的矩阵快速幂 hdu5950 hdu3369 hdu 3483

HDU 5690 矩阵快速幂

矩阵快速幂计算hdu1575

hdu 2604 递推 矩阵快速幂

HDU 4549 (费马小定理+矩阵快速幂+二分快速幂)