poj 3735 稀疏矩阵矩阵快速幂

设人数为 $n$,构造 $(n + 1) \times (n + 1)$ 的矩阵

得花生:
将改行的最后一列元素 $+ 1$

\begin{gather}
\begin{bmatrix}
1 & 0 & 0 & 1 \\
0 & 1 & 0 & 0 \\
0 & 0 & 1 & 0 \\
0 & 0 & 0 & 1
\end{bmatrix}
\times
\begin{bmatrix}
x \\
y \\
z \\
1 \\
\end{bmatrix}
=
\begin{bmatrix}
x + 1 \\
y \\
z \\
1\\
\end{bmatrix}
\end{gather}

吃花生:
将一行的元素全部清零

\begin{gather}
\begin{bmatrix}
1 & 0 & 0 & 0\\
0 & 0 & 0 & 0 \\
0 & 0 & 1 & 0 \\
0 & 0 & 0 & 1
\end{bmatrix}
\times
\begin{bmatrix}
x \\
y \\
z \\
1 \\
\end{bmatrix}
=
\begin{bmatrix}
x \\
0 \\
z \\
1\\
\end{bmatrix}
\end{gather}

交换两行

\begin{gather}
\begin{bmatrix}
0 & 1 & 0 & 0 \\
1 & 0 & 0 & 0 \\
0 & 0 & 1 & 0 \\
0 & 0 & 0 & 1
\end{bmatrix}
\times
\begin{bmatrix}
x \\
y \\
z \\
1 \\
\end{bmatrix}
=
\begin{bmatrix}
y \\
x \\
z \\
1\\
\end{bmatrix}
\end{gather}

普通矩阵快速幂
TLE
稀疏矩阵矩阵快速幂

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>

using namespace std;
const int N = 110;

#define LL long long

LL n, m, k;
struct Matrix {LL M[N][N];} A;

Matrix operator * (Matrix &a, Matrix &b) {
    Matrix ret;
    memset(ret.M, 0, sizeof ret.M);
    for(int i = 1; i <= n; i ++)
        for(int j = 1; j <= n; j ++)
            if(a.M[i][j])
                for(int K = 1; K <= n; K ++)
                    ret.M[i][K] = (ret.M[i][K] + a.M[i][j] * b.M[j][K]);
    return ret;
}

Matrix Ksm(int p) {
    Matrix Ans;
    memset(Ans.M, 0, sizeof Ans.M);
    for(int i = 1; i <= n; i ++) Ans.M[i][i] = 1;
    while(p) {
        if(p & 1) Ans = Ans * A;
        A = A * A;
        p >>= 1;
    }
    return Ans;
}

int main() {
    while(1) {
        cin >> n >> k >> m;
        if(n == 0 && m == 0 && k == 0) return 0;
        n ++;
        char s[10];
        memset(A.M, 0, sizeof A.M);
        for(int i = 1; i <= n; i ++) A.M[i][i] = 1;
        for(int i = 1; i <= m; i ++) {
            scanf("%s", s);
            if(s[0] == ‘g‘) {
                int x; std:: cin >> x;
                A.M[x][n] ++;
            } else if(s[0] == ‘e‘) {
                int x; std:: cin >> x;
                for(int j = 1; j <= n; j ++) A.M[x][j] = 0;
            } else {
                int x, y; std:: cin >> x >> y;
                swap(A.M[x], A.M[y]);
            }
        }
        Matrix Answer = Ksm(k);
        for(int i = 1; i < n; i ++) cout << Answer.M[i][n] << " ";
        printf("\n");
    }
    return 0;
}

原文地址:https://www.cnblogs.com/shandongs1/p/9683470.html

时间: 2024-10-12 11:41:54

poj 3735 稀疏矩阵矩阵快速幂的相关文章

[POJ 3734] Blocks (矩阵快速幂、组合数学)

Blocks Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3997   Accepted: 1775 Description Panda has received an assignment of painting a line of blocks. Since Panda is such an intelligent boy, he starts to think of a math problem of paint

poj 3070 Fibonacci (矩阵快速幂求斐波那契数列的第n项)

题意就是用矩阵乘法来求斐波那契数列的第n项的后四位数.如果后四位全为0,则输出0,否则 输出后四位去掉前导0,也...就...是...说...输出Fn%10000. 题目说的如此清楚..我居然还在%和/来找后四位还判断是不是全为0还输出时判断是否为0然后 去掉前导0.o(╯□╰)o 还有矩阵快速幂的幂是0时要特判. P.S:今天下午就想好今天学一下矩阵乘法方面的知识,这题是我的第一道正式接触矩阵乘法的题,欧耶! #include<cstdio> #include<iostream>

poj 3070 Fibonacci 矩阵快速幂

题目链接:http://poj.org/problem?id=3070 In the Fibonacci integer sequence, F0 = 0, F1 = 1, and Fn = Fn − 1 + Fn − 2 for n ≥ 2. For example, the first ten terms of the Fibonacci sequence are: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, … An alternative formula for t

POJ 3734 Blocks (矩阵快速幂)

题目链接:http://poj.org/problem?id=3734 <挑战程序设计竞赛>202页.与单纯的用递推式与矩阵快速幂求第N项不同,设染到第i个方块为止,红绿都是偶数的方案数目为a,红绿恰有一个是偶数方案数目为b,红绿都是奇数方案数目为c, 则: a[i+1] = 2 * a[i] + b[i] b[i+1] = 2 * a[i]+2 * b[i]+2 * c[i] c[i+1] = b[i] + 2 * c[i] 之后构建3*3矩阵求解 代码: 1 typedef vector&

poj 3070 Fibonacci (矩阵快速幂乘/模板)

题意:给你一个n,输出Fibonacci (n)%10000的结果 思路:裸矩阵快速幂乘,直接套模板 代码: #include <cstdio> #include <cstring> #include <iostream> using namespace std; typedef long long ll; const int N=2,M=2,P=2; const int MOD=10000; struct Matrix { ll m[N][N]; }; Matrix

POJ 3734 Blocks(矩阵快速幂加递推)

Blocks Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6133   Accepted: 2931 Description Panda has received an assignment of painting a line of blocks. Since Panda is such an intelligent boy, he starts to think of a math problem of paint

POJ——3070Fibonacci(矩阵快速幂)

Fibonacci Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 12329   Accepted: 8748 Description In the Fibonacci integer sequence, F0 = 0, F1 = 1, and Fn = Fn − 1 + Fn − 2 for n ≥ 2. For example, the first ten terms of the Fibonacci sequenc

POJ 3070 Fibonacci(矩阵快速幂)

Description In the Fibonacci integer sequence, F0 = 0, F1 = 1, and Fn = Fn ? 1 + Fn ? 2 for n ≥ 2. For example, the first ten terms of the Fibonacci sequence are: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, - An alternative formula for the Fibonacci sequence is

快速乘、快速幂(矩阵快速幂)

当mod一个大数p的时候,还有进行乘法的时候可能会爆long long的时候,就用快速乘或者快速幂. 参考:http://www.cnblogs.com/whywhy/p/5066730.html 先上模板: 快速乘: ll multi(ll a,ll b,ll m) { ll ans=0; while(b) { if(b&1) (ans+=a) %= m; (a=a*2) %= m; b/=2; } return ans; } 快速幂: ll pow_mod(ll a,ll b,ll m) {