zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    数据结构总结——线段树
    [bzoj2131]免费的馅饼 树状数组优化dp
    [机房练习赛7.26] YYR字符串
    博客已搬家
    AFO
    COGS-2551 新型武器
    UVALive-3716 DNA Regions
    UVALive-4850 Installations
    UVALive-3983 Robotruck
    UVA-10859 Placing Lampposts
  • 原文地址:https://www.cnblogs.com/pbvrvnq/p/8530153.html
Copyright © 2011-2022 走看看