• POJ 3735 Training little cats 矩阵快速幂


    http://poj.org/problem?id=3735

    给定一串操作,要这个操作连续执行m次后,最后剩下的值。

    记矩阵T为一次操作后的值,那么T^m就是执行m次的值了。(其实这个还不太理解,但是数据一相乘,就是ans)

    构造一个0--n的单位矩阵,用第0行作为各个猫的值,这样的话,用A={1,0,0,0}一乘就是每个毛的ans。

    构造单位矩阵的意义就是他们矩阵自己相乘的时候,能够保留自己的值。

    这个矩阵很分散,0的那些可以特判掉不枚举多一程O(n)了。这需要你的矩阵乘法是一个一个加上去的,而不是集中一起加上去的。

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    #define inf (0x3f3f3f3f)
    typedef long long int LL;
    
    #include <iostream>
    #include <sstream>
    #include <vector>
    #include <set>
    #include <map>
    #include <queue>
    #include <string>
    const int maxn = 100 + 2;
    struct Matrix {
        LL a[maxn][maxn];
        int row;
        int col;
    };
    struct Matrix c; //这个要多次用到,栈分配问题,maxn不能开太大,
    struct Matrix matrix_mul  (struct Matrix a,struct Matrix b,int MOD) {
        //求解矩阵a*b%MOD
        struct Matrix c = {0};
        //LL的时候更加是,空间是maxn*maxn的,这样时间用得很多
        c.row=a.row; //行等于第一个矩阵的行
        c.col=b.col; //列等于第二个矩阵的列
        for (int i = 0; i <= a.row; ++i) {
            for (int k = 0; k <= a.col; ++k) {
                if (a.a[i][k]) {//应付稀疏矩阵
                    for (int j = 0; j <= b.col; ++j) {
                        c.a[i][j] += a.a[i][k] * b.a[k][j];
                    }
                }
            }
        }
        return c;
    }
    struct Matrix quick_matrix_pow  (struct Matrix ans,struct Matrix base,int n,int MOD) {
        //求解a*b^n%MOD
    //    cout << n << endl;
        while (n) {
            if (n&1) {
                ans=matrix_mul(ans,base,MOD);//传数组不能乱传,不满足交换律
            }
            n>>=1;
            base=matrix_mul(base,base,0);
        }
        return ans;
    }
    int n, m, k;
    void work() {
        struct Matrix b = {0};
        b.row = b.col = n;
        for (int i = 0; i <= n; ++i) {
            b.a[i][i] = 1;
        }
        for (int i = 1; i <= k; ++i) {
            char str[11];
            int a, c;
            scanf("%s", str);
            if (str[0] == 'g') {
                scanf("%d", &a);
                ++b.a[0][a];
            } else if (str[0] == 'e') {
                scanf("%d", &a);
                for (int j = 0; j <= n; ++j) {
                    b.a[j][a] = 0;
                }
            } else {
                scanf("%d%d", &a, &c);
                for (int j = 0; j <= n; ++j) {
                    swap(b.a[j][a], b.a[j][c]);
                }
            }
        }
    //    for (int i = 0; i <= n; ++i) {
    //        for (int j = 0; j <= n; ++j) {
    //            cout << b.a[i][j] << " ";
    //        }
    //        cout << endl;
    //    }
        struct Matrix tt = {0};
        tt.row = 1;
        tt.col = n;
        tt.a[0][0] = 1;
        struct Matrix ans = quick_matrix_pow(tt, b, m, 111);
        for (int i = 1; i <= n; ++i) {
            printf("%lld ", ans.a[0][i]);
        }
        printf("
    ");
    }
    int main() {
    #ifdef local
        freopen("data.txt","r",stdin);
    #endif
        while (scanf("%d%d%d", &n, &m, &k) != EOF && n + m + k) work();
        return 0;
    }
    View Code
  • 相关阅读:
    POWERDESIGNER中显示样式设置
    DatagridView 最后编辑状态数据无法自动提交的问题
    oracle 10G以上版本 树形查询新加的几个功能
    net farmework 4安装不了 原因是 HRESULT 0xc8000222
    npoi 导出
    oracle rowtype
    fiddler https
    一次linux站点安装经验
    小米手机安装https证书报错:无法安装该证书 因为无法读取该证书文件
    日志系统
  • 原文地址:https://www.cnblogs.com/liuweimingcprogram/p/5942591.html
Copyright © 2020-2023  润新知