ZOJ 2853 Evolution 【简单矩阵快速幂】

这道题目第二次看的时候才彻底理解了是什么意思

把题目转化为数学模型分析后就是 有一个初始序列, 有一个进化率矩阵

求的是初始序列 与进化率矩阵进行 m 次运算后, 初始序列最后一位的答案

那么显然,可以对进化率矩阵进行快速幂计算

Example

Let‘s assume that P(0, 1) = P(1, 2) = 1, and at the beginning of a sub-process, the populations of 0, 1, 2 are 40, 20 and 10 respectively, then at the end of the sub-process, the populations are 0, 40 and 30 respectively.

这个栗子看懂了这题就会懂了。

Source Code:

//#pragma comment(linker, "/STACK:16777216") //for c++ Compiler
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <cstring>
#include <cmath>
#include <stack>
#include <string>
#include <map>
#include <set>
#include <list>
#include <queue>
#include <vector>
#include <algorithm>
#define Max(a,b) (((a) > (b)) ? (a) : (b))
#define Min(a,b) (((a) < (b)) ? (a) : (b))
#define Abs(x) (((x) > 0) ? (x) : (-(x)))
#define MOD 1000000007
#define pi acos(-1.0)

using namespace std;

typedef long long           ll      ;
typedef unsigned long long  ull     ;
typedef unsigned int        uint    ;
typedef unsigned char       uchar   ;

template<class T> inline void checkmin(T &a,T b){if(a>b) a=b;}
template<class T> inline void checkmax(T &a,T b){if(a<b) a=b;}

const double eps = 1e-7      ;
const int N = 210            ;
const int M = 1100011*2      ;
const ll P = 10000000097ll   ;

int n, m;

struct Mat{
    double mat[N][N];
};

Mat operator * (Mat a, Mat b){
    Mat c;
    memset(c.mat, 0, sizeof(c.mat));
    for(int k = 0; k < n; ++k){
        for(int i = 0; i < n; ++i){
            if(a.mat[i][k] <= 0)    continue;   //
            for(int j = 0; j < n; ++j){
                if(b.mat[k][j] <= 0)    continue;   //
                c.mat[i][j] += a.mat[i][k] * b.mat[k][j];
            }
        }
    }
    return c;
}

Mat operator ^ (Mat a, int k){
    Mat c;
    for(int i = 0; i < n; ++i){
        for(int j = 0; j < n; ++j){
            c.mat[i][j] = (i == j); //init
        }
    }
    for(; k; k >>= 1){
        if(k & 1)   c = c * a;  //key
        a = a * a;
    }
    return c;
}

int main(){
    int i, j, t, k, u, v, numCase = 0;
    while(EOF != scanf("%d%d",&n,&m)){
        if(0 == n && 0 == m)    break;
        double val;
        Mat a, b;
        memset(a.mat, 0, sizeof(a.mat));
        memset(b.mat, 0, sizeof(b.mat));
        for(i = 0; i < n; ++i)  b.mat[i][i] = 1;
        for(i = 0; i < n; ++i)  scanf("%lf", &a.mat[i][i]);
        scanf("%d",&t);
        while(t--){
            scanf("%d%d%lf",&u,&v,&val);
            b.mat[u][u] -= val; //
            b.mat[u][v] = val;  //
        }
        b = b ^ m;
        double cur = 0;
        for(i = 0; i < n; ++i){
            cur += b.mat[i][n - 1] * a.mat[i][i];
        }
        /*
        for(i = 0; i < n; ++i){
            for(j = 0; j < n; ++j){
                cout << c.mat[i][j] << ‘ ‘;
            }
            cout << endl;
        }
        */
        printf("%.0lf\n",cur);
    }
    return 0;
}

/*
3 1
40 20 10
2
0 1 1.0
1 2 1.0
*/
时间: 2024-09-30 16:35:30

ZOJ 2853 Evolution 【简单矩阵快速幂】的相关文章

zoj 2853 Evolution(矩阵快速幂)

Evolution is a long, long process with extreme complexity and involves many species. Dr. C. P. Lottery is currently investigating a simplified model of evolution: consider that we haveN (2 <= N <= 200) species in the whole process of evolution, inde

HDU3306Another kind of Fibonacci(简单矩阵快速幂)

哎,本来是想学学矩阵构造的方法的,,突然发现自己不用看直接就会yy构造... 看下右边有什么.. 题目地址:Another kind of Fibonacci AC代码: #include<iostream> #include<cstdio> #include<cstring> #include<string> using namespace std; const int mod=10007; int p[4][4],a[4][4],tmp[4][4]; i

UVA10870—Recurrences(简单矩阵快速幂)

题目链接:https://vjudge.net/problem/UVA-10870 题目意思: 给出a1,a2,a3,a4,a5------ad,然后算下面这个递推式子,简单的矩阵快速幂,裸题,但是第一个次遇到了矩阵大小不确定的矩阵快速幂,而且在这道题里面第一次明白了如何构造矩阵.算是矩阵快速幂的学习的一个小里程碑吧. f(n) = a1 *f(n - 1) + a2 *f(n - 2) + a3 *f(n - 3) + - + ad* f(n - d),  n > d.求f(n) 代码: 1

Evolution(矩阵快速幂)

Evolution Time Limit: 5 Seconds      Memory Limit: 32768 KB Description Evolution is a long, long process with extreme complexity and involves many species. Dr. C. P. Lottery is currently investigating a simplified model of evolution: consider that w

Codeforces - 185A 简单矩阵快速幂

题意:求第n个三角形内部的上三角形个数 对每个三角形分别维护上下三角形个数,记为\(dp[1][i],dp[2][i]\) 规律很明显是 \(dp[1][i+1]=3*dp[1][i]+dp[2][i]\) \(dp[2][i+1]=3*dp[2][i]+dp[1][i]\) 别忘了快速幂里也要long long,白送了个TLE /*H E A D*/ inline ll mod(ll a){return a%MOD;} struct Matrix{ ll mt[5][5],r,c; void

ZOJ 3497 Mistwald(矩阵快速幂)

题目: Mistwald Time Limit: 2 Seconds      Memory Limit: 65536 KB In chapter 4 of the game Trails in the Sky SC, Estelle Bright and her friends are crossing Mistwald to meet their final enemy, Lucciola. Mistwald is a mysterious place. It consists of M *

ZOJ - 3690 Choosing number 矩阵快速幂

题目大意:有n个人排成一行,有m个数字,每个人可以选择1 – m的任一个数字,但有一个限制,如果相邻的两个人选择相同的数字的话,这个数字必须大于k 问有多少种选择方法 解题思路:变化矩阵为(m-k, k, m - k, k - 1),按行的写 设前一个数为j 如果j大于k的话,那么j后面可以跟上任一个数 如果j小于等于k,那么j后面只能跟上不等于k的数 如果有p种情况为前一个数大于k的,q种情况为前一个数小于等于k的,由上面可得,当前这个数大于k的情况有 p * (n -k) + q * (n

HDU - 1005 Number Sequence(简单矩阵快速幂)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1005 题意:f(1) = 1, f(2) = 1, f(n) = (A * f(n - 1) + B * f(n - 2)) mod 7. 就是这道题目,然而找了一晚上的错误 \("▔□▔)/\("▔□▔)/\("▔□▔)/. 1 #include <iostream> 2 #include <cstring> 3 using namespace std;

hdu------(1757)A Simple Math Problem(简单矩阵快速幂)

A Simple Math Problem Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2791    Accepted Submission(s): 1659 Problem Description Lele now is thinking about a simple function f(x). If x < 10 f(x) =