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;
}
原文地址:https://www.cnblogs.com/pbvrvnq/p/8530153.html