POJ 3233 二分二分矩阵

本文介绍了一种利用二分法和矩阵快速幂解决特定类型数学问题的方法。通过两次二分,一次针对矩阵的幂次,另一次针对求和项数,有效地降低了问题的复杂度。文中提供了一个C++实现示例,展示了如何使用矩阵乘法和加法来高效计算形如A+A^2+...+A^k的表达式。

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

/*

 由于对二分的不熟练,这道题不知坑了多久... 
 这道题两次二分,相当经典。首先我们知道,A^i可以二分求出。然后我们需要对整个题目的数据规模k进行二分。
 比如,当k=6时,有: A + A^2 + A^3 + A^4 + A^5 + A^6 =(A + A^2 + A^3) + A^3*(A + A^2 + A^3)
 应用这个式子后,规模k减小了一半。我们二分求出A^3后再递归地计算A + A^2 + A^3,即可得到原问题的答案。

*/

#include<iostream>
#include<cstdio>
#include<cstring>
#include<fstream>
#include<cmath>
using namespace std;
struct Matrix
{
    int a[32][32];
}a1;
int n,k,mod;
Matrix mult2(Matrix A,Matrix B){ /// 矩阵乘法
    Matrix C;
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            C.a[i][j]=0;
            for(int k=0;k<n;k++){
                C.a[i][j] += A.a[i][k]*B.a[k][j];
                C.a[i][j] %= mod;
            }
        }
    }
    return C;
}

Matrix add(Matrix A,Matrix B){ /// 矩阵加法
    Matrix C;
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            C.a[i][j] = (A.a[i][j]+B.a[i][j])%mod;
        }
    }
    return C;
}

Matrix pow(Matrix a,int k){ /// 二分矩阵快速幂
    if(k == 1)return a;
    if(k % 2)return mult2(pow(a,k-1),a);
    return pow(mult2(a,a),k/2);
}

Matrix sum(int k){ /// 二分快速求和
    if(k<= 1)  return a1; 
    if(k % 2)  return add(sum(k-1) , pow(a1,k));
    else{
        Matrix temp = sum(k/2);
        return add(temp , mult2(temp,pow(a1,k/2)));
    }
}
int main()
{
    int i,j;
    scanf("%d%d%d",&n,&k,&mod) ;
    for(i =0; i < n;i++)
        for(j =0 ;j < n;j++)
            scanf("%d",&a1.a[i][j]);
    Matrix ans;
    ans = sum(k);
    for(i =0 ;i< n;i++) {
        for(j=0 ;j < n - 1;j++)
            printf("%d ",ans.a[i][j]);
        printf("%d\n",ans.a[i][j]);
    }
    return 0;
}
/*

2 2 4
0 1 
1 1

*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值