题意:用1 X 2的矩形填充4 X n的矩形,共有多少种不同方法。

思路:原来写过一个2*n的,递推推公式就行。
如果n-1行填满的话,第n行只有一种情况,如果n-2行填满的话,有4种情况;

如果n-3行填满的话,有2种情况;

如果n-4行填满的话,有3种情况;

如果n-5行填满的话,有2种情况;

如果n-6行填满的话,有3种情况;

...

f[n] = f[n-1] + 4*f[n-2] + 2 * [ f[n-3] + f[n-5] + f[n-7] +.... ] + 3 * [ f[n-4] + f[n-6] + f[n-8] +... ] ; (1)

f[n - 2] = f[n-3] + 4*f[n-4] + 2 * [ f[n-5] + f[n-7] + f[n-9]+..] + 3 * [ f[n-6] + f[n-8] + f[n-10] +.. ] ;(2)

(1) - (2) 化简得 f[n] = f[n-1] + 5f[n-2] + f[n-3] - f[n-4];

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <vector>
#define INF 0x3f3f3f3f
using namespace std;
int a[4], n, m;
typedef long long LL;
struct data{
    LL mat[4][4];
};
data mul(data a, data b)
{
    data res;
    memset(res.mat, 0, sizeof(res.mat));
    for(int i = 0; i < 4; i++)
        for(int j = 0; j < 4; j++)
            for(int i2 = 0; i2 < 4; i2++)
                res.mat[i][j] = ((res.mat[i][j]+(a.mat[i][i2]*b.mat[i2][j])%m)%m+m)%m;
    return res;
}
int main()
{
    a[0] = 1, a[1] = 1, a[2] = 5, a[3] = 11;
    while(~scanf("%d %d", &n, &m) && n + m) {
        if(n < 4) {
            printf("%d\n", a[n] % m);
            continue;
        }
        n -= 3;
        data base, res;
        memset(base.mat, 0, sizeof(base.mat));
        memset(res.mat, 0, sizeof(res.mat));
        for(int i = 0; i < 4; i++)
            base.mat[i][i] = 1;
        res.mat[0][0] = 1, res.mat[0][1] = 5;
        res.mat[0][2] = 1, res.mat[0][3] = -1;
        res.mat[1][0] = 1, res.mat[2][1] = 1;
        res.mat[3][2] = 1;
        while(n) {
            if(n % 2)
                base = mul(res, base);
            res = mul(res, res);
            n >>= 1;
        }
        LL res2 = 0;
        for(int i = 0; i < 4; i++)
            res2 = (res2 + (base.mat[0][i] * a[3 - i])%m)%m;
        printf("%lld\n", res2);
    }
    return 0;
}