矩阵快速幂(推导+模板+例题详解)

13 篇文章 0 订阅
4 篇文章 0 订阅

整数快速幂:
在这里插入图片描述
分解成二进制形式易得程序

int fastpow(int base,int n,int mod){
	int ans=1;
	while(n){
		if(n&1) ans*=base%mod;
		base*=base;
		n>>=1;
	}
	return ans%mod;
}

快速幂复杂度是O(logn),不用快速幂是O(n)

矩阵快速幂:
把整数乘法改成矩阵乘法,原理一样

struct Mat{
    double m[maxn+5][maxn+5];
    Mat(){
        memset(m,0,sizeof m);//构造函数初始化为0阵
    }
    void build(){//建单位矩阵
        for(int i=0;i<=maxn;i++){
            m[i][i]=1;
        }
    }
};
Mat operator*(Mat &a,Mat &b){
    Mat t;
    for(int i=1;i<=N;i++){
        for(int j=1;j<=N;j++){
            for(int k=1;k<=N;k++){
                t.m[i][j]+=a.m[i][k]*b.m[k][j];
            }
        }
    }
    return t;
}

void ksm(int n){//和整数快速幂格式完全一样
    ans.build();
    while(n>0){
        if(n&1){
            ans=ans*a;
        }
        a=a*a;
        n>>=1;
    }
}

模板题:
https://codeforces.com/gym/102966/problem/C
C. CLETS Patrols
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
The Corporation Of Ludicrously Evil Topography and Scouring (CLETS) is working on a new way to organize their henchmen’s patrols so that they will be impossible to predict for a certain handsome british spy that would try to infiltrate their base. To that end, when a henchman reaches a post, a computer will randomly pick to which post the henchman should go next.

By some classified means, we have acquired the probability distributions that the computers use to choose where to send the henchmen next. Your task is to use this information to determine, for every post, the probability that a guard will be there after M steps, so that our friend, the handsome british spy, can plan the safest route to the CLETS base.

A step is defined as moving from one post to another, or waiting in the same post, should the computer decide that. The Guard start their shift on the first post.

Input
The fist line contains two integers separated by a space, N and M where (1≤N≤200) and (1≤M≤10000): the number of posts, and the number of steps we are interested in. The next N lines contain exactly N numbers separated by a space where the j-th number on line i+1 represents the probability that the computer will send a guard to the j-th post from the i-th post.

Output
Print N lines; in the i-th line, print the probability that a guard will be in post number i after M steps.

Your answer is considered correct if its absolute or relative error doesn’t exceed 10−4.

Example
inputCopy
2 2
0.75 0.25
0.5 0.5
outputCopy
0.6875
0.3125

题意:给出一个有向完全图<V,E>,V中有N个顶点,从1号顶点出发跳转M次,每次从顶点vi跳转到顶点vj的概率为<vi,vj>,求最终落在各个顶点的概率。
思路:通过观察找到矩阵的递推关系(step=1,2,3…),通过递推关系找到通项公式,然后用快速幂解出。在这里插入图片描述

#include <bits/stdc++.h>
const int maxn=250;
using namespace std;
int N,M;
struct Mat{
    double m[maxn+5][maxn+5];
    Mat(){
        memset(m,0,sizeof m);
    }
    void build(){
        for(int i=0;i<=maxn;i++){
            m[i][i]=1;
        }
    }
}a,a2,ans;
Mat operator*(Mat &a,Mat &b){
    Mat t;
    for(int i=1;i<=N;i++){
        for(int j=1;j<=N;j++){
            for(int k=1;k<=N;k++){
                t.m[i][j]+=a.m[i][k]*b.m[k][j];
            }
        }
    }
    return t;
}

void ksm(int n){
    ans.build();
    while(n>0){
        if(n&1){
            ans=ans*a;
        }
        a=a*a;
        n>>=1;
    }
}

int main()
{
    //cout << "Hello world!" << endl;

    cin>>N>>M;
    for(int i=1;i<=N;i++){
        for(int j=1;j<=N;j++){
            cin>>a.m[i][j];
            a2.m[i][j]=a.m[i][j];
        }
    }
    ksm(M-1);
    for(int i=1;i<=N;i++){
        double temp=0;
        for(int j=1;j<=N;j++){
            temp+=ans.m[1][j]*a2.m[j][i];
        }
        printf("%.4f\n",temp);
    }
    return 0;
}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值