整数快速幂:
分解成二进制形式易得程序
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;
}