【poj3233】Matrix Power Series(递推+矩阵快速幂)

该博客介绍了如何解决POJ3233问题,重点讨论了利用递推关系和矩阵快速幂优化算法以提高效率,而非采用朴素方法。博主分享了他们的思考过程和代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

传送门

题解

用朴素的矩阵快速幂的话时间无法承受。其实这道题的思路挺奇特的,不是自己想出来的很不爽。
这里有一个递推的思路:考虑k能不能从之前的状态转移过来。答案是肯定的。
k%2==0 时:

sum(k)=i=1kAk=(1+Ak2)(A+A2++Ak2)

k%2!=0
sum(k)=i=1kAk=A+(A+Ak2)(A+A2++Ak2)

也就是说先计算出 sum(k2) 的值就可以经过很少的计算得出 sum(k) 的值,那么我们可以不断递归下去。
有必要说明一点:第一个公式出现了1,它其实就代表了一个单位矩阵,即
I=1000010000100001

满足 AI=IA=A A 为任意矩阵)

代码

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;

struct hp{
    int a[35][35];
}A,unit;
int n,k,m;

inline hp jia(hp a,hp b){
    hp c;
    for (int i=1;i<=n;++i)
      for (int j=1;j<=n;++j)
        c.a[i][j]=(a.a[i][j]+b.a[i][j])%m;
    return c;
}

inline hp cheng(hp a,hp b){
    hp c;
    memset(c.a,0,sizeof(c.a));
    for (int i=1;i<=n;++i)
      for (int j=1;j<=n;++j)
        for (int k=1;k<=n;++k)
          c.a[i][j]=(c.a[i][j]+a.a[i][k]*b.a[k][j]%m)%m;
    return c;
}

inline hp fast_pow(hp a,int p){
    hp ans=unit;
    for (;p;p>>=1,a=cheng(a,a))
      if (p&1)
        ans=cheng(ans,a);
    return ans;
}

inline hp doit(int k){
    if (k==1) return A;
    hp now=doit(k/2);
    if (k%2==0){
        hp x=fast_pow(A,k/2);
        x=jia(unit,x);
        x=cheng(x,now);
        return x;
    }
    else{
        hp x=fast_pow(A,k/2+1);
        x=jia(A,x);
        x=cheng(x,now);
        x=jia(A,x);
        return x;
    }
}

int main(){
    scanf("%d%d%d",&n,&k,&m);
    for (int i=1;i<=n;++i)
      for (int j=1;j<=n;++j)
        scanf("%d",&A.a[i][j]);
    for (int i=1;i<=n;++i)
      unit.a[i][i]=1;
    hp ans=doit(k);
    for (int i=1;i<=n;++i)
      for (int j=1;j<=n;++j)
        printf("%d%c",ans.a[i][j]," \n"[j==n]);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值