• POj 3420


    强行一道矩阵递推, 强行暴力矩阵水过
    题目好懂就不说了, 其实我们可以先打一个暴力, 愉快地打完, 就是枚举i-1行的状态, 判断从这个状态可以使第i行的那些状态被更新, 然后就可以去想矩阵了, 那么很好想暴力一个16*16的矩阵直接弄好每个状态可以对应的更新, 然后自乘n次最右下角的元素就是答案了, 由于我这个题一开始想到的就是状压, 听说可以优化成4*4的矩阵, 那么就留给读者自己去想了, 其实我也不会, 手动滑稽。。。

    #include <cstdio>
    #include <cstring>
    
    typedef long long LL;
    
    const int P = 16;
    const LL d[P][P] = {
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 
        0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 
        0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 
        0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 
        0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
        0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
        0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 
        0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 
        0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 
        0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 
        1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1};
    #define rep(i, s, t) for(int i = s; i <= t; ++i)
    
    namespace Galaxy {
        int Mod, n;
    
        struct Matrix {
            LL x[P][P];
            Matrix() {memset(x, 0, sizeof x);}
        }Ans, Tmp, unit;
    
        Matrix operator * (Matrix a, Matrix b) {
            rep(i, 0, 15)rep(j, 0, 15) Ans.x[i][j] = 0;
    
            rep(i, 0, 15)
                rep(j, 0, 15)
                    rep(k, 0, 15)
                        Ans.x[i][j] = (Ans.x[i][j]+a.x[i][k] * b.x[k][j] % Mod) % Mod;
            return Ans;
        }
    
        Matrix operator ^ (Matrix a, int b) {
            Tmp = a;
            for(; b; b >>= 1, a = a*a)
                if(b & 1) Tmp = Tmp * a;
            return Tmp;
        }
    
        void solve() {
            while(scanf("%d%d", &n, &Mod) == 2 && n + Mod) {
                memcpy(unit.x, d, sizeof d);
                unit = unit ^ (n-1);
                printf("%lld
    ", unit.x[15][15] % Mod);
            }
        }
    };
    
    int main() {
        Galaxy :: solve();
        return 0;
    }
  • 相关阅读:
    db.Exec和db.Query的区别
    golang两种get请求获取携带参数的方式
    gin实现中间件middleware
    gin操作session
    笔札-有触动的句子
    并发的基本概念
    售货员的难题
    传球游戏之最小总代价
    状压dp入门
    [COCI 2010] OGRADA
  • 原文地址:https://www.cnblogs.com/pbvrvnq/p/8530153.html
Copyright © 2020-2023  润新知