zoukankan      html  css  js  c++  java
  • POJ3735 Training little cats 矩阵快速幂 + 矩阵快速幂优化

    有n只猫,每只猫初始石刻没糖果。 进行m次重复的k次操作。

    g i 给第i只猫一个糖果

    s i j  交换第i只猫和第j只猫的糖果

    c i 吃掉第i只猫的所有糖果

    m <=1e9 明显是用矩阵快速幂处理。 难点在于建立转移矩阵。

    注意到只需对单位矩阵操作。对于n只猫建立 n+1 * 1 的矩阵,多的一行存放 1 用来转移。

    g i ,即对单位矩阵 E的第i行第n + 1列 set 为1 

    s i j 即对单位矩阵的i j 行交换

    c i 即对单位矩阵的第i行clear

    如此就可以矩阵快速幂了 。

    注意到矩阵是稀疏矩阵,考虑优化。

    #pragma warning(disable:4996)
    
    #include<iostream>
    #include<algorithm>
    #include<bitset>
    #include<tuple>
    #include<unordered_map>
    #include<fstream>
    #include<iomanip>
    #include<string>
    #include<cmath>
    #include<cstring>
    #include<vector>
    #include<map>
    #include<set>
    #include<list>
    #include<queue>
    #include<stack>
    #include<sstream>
    #include<cstdio>
    #include<ctime>
    #include<cstdlib>
    #define INF 0x3f3f3f3f
    #define inf 0x7FFFFFFF
    #define MOD 998244353
    #define moD 1000000003
    #define pii pair<int,string>
    #define eps 1e-8
    #define equals(a,b) (fabs(a-b)<eps)
    #define bug puts("bug")
    #define re  register
    #define fi first
    #define se second
    const int maxn = 1e6 + 5;
    const double Inf = 10000.0;
    const double PI = acos(-1.0);
    typedef  long long ll;
    typedef unsigned long long ull;
    using namespace std;
    
    struct Mat {
        ll m[105][105];
    };
    
    Mat E;
    ll n, m, k;
    
    void init(int n) {
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) if(i == j) E.m[i][j] = 1;
        }
    }
    
    Mat mul(const Mat& a, const Mat& b) {
        Mat c;
        for (int i = 0; i < n + 1; i++) for (int j = 0; j < n + 1; j++) c.m[i][j] = 0;
        for (int i = 0; i < n + 1; i++) {
            for (int k = 0; k < n + 1; k++) {
                if(a.m[i][k])
                for (int j = 0; j < n + 1; j++) c.m[i][j] = (c.m[i][j] + a.m[i][k] * b.m[k][j] )  ;
            }
        }
        return c;
    }    
    
    Mat mult(const Mat& a, const Mat& b) {
        Mat c;
        for (int i = 0; i < n + 1; i++) {
            for (int j = 0; j < 1; j++) {
                c.m[i][j] = 0;
                for (int k = 0; k < n + 1; k++) c.m[i][j] = (c.m[i][j] + a.m[i][k] * b.m[k][j] ) ;
            }
        }
        return c;
    }
    
    Mat ans;
    Mat base;
    
    Mat quickPower(Mat a, ll b) {
        ans = E;
        base = a;
        while (b) {
            if (b & 1) ans = mul(ans, base);
            base = mul(base, base);
            b >>= 1;
        }
        return ans;
    }
    
    Mat q;
    
    
    int main() {
        init(105 + 1);
        while (scanf("%lld%lld%lld", &n, &m, &k), n || m || k) {
            Mat s;
            q = E;
            char op[3];
            int x, y;
            for (int i = 0; i < k; i++) {
                scanf("%s", op);
                if (strcmp(op, "g") == 0) {
                    scanf("%d", &x);
                    Mat tmp = E;
                    tmp.m[x - 1][n] = 1;
                    q = mul(tmp, q);
                }
                else if (strcmp(op, "s") == 0) {
                    scanf("%d%d", &x, &y);
                    Mat tmp = E;
                    tmp.m[x - 1][x - 1] = 0;
                    tmp.m[x - 1][y - 1] = 1;
                    tmp.m[y - 1][y - 1] = 0;
                    tmp.m[y - 1][x - 1] = 1;
                    q = mul(tmp, q);
                }
                else {
                    scanf("%d", &x);
                    Mat  tmp = E;
                    tmp.m[x - 1][x - 1] = 0;
                    q = mul(tmp, q);
                }
            }
            q = quickPower(q, m);
            for (int i = 0; i < n; i++) s.m[i][0] = 0;
            s.m[n][0] = 1;
            q = mult(q, s);
            for (int i = 0; i < n; i++) printf("%lld ", q.m[i][0]);
            puts("");
        }
    }
  • 相关阅读:
    Poj-1088-滑雪
    Poj-2250-Compromise
    CF
    KMP算法
    01背包
    NY 269 VF
    PHP--1+2+3……100=?
    PHP企业发放的奖金--if...elseif...
    2019年中级考试题(附答案)
    PHP的IF条件语句-- 输入一个数字进行判断等级
  • 原文地址:https://www.cnblogs.com/hznumqf/p/13354670.html
Copyright © 2011-2022 走看看