POJ_3420_Quad Tiling

来源:互联网 发布:蓝月传奇淘宝礼包 编辑:程序博客网 时间:2024/05/20 02:53
Quad Tiling
Time Limit: 1000MS
Memory Limit: 65536KTotal Submissions: 4410
Accepted: 2013

Description

Tired of the Tri Tiling game finally, Michael turns to a more challengeable game, Quad Tiling:

In how many ways can you tile a 4 × N (1 ≤ N ≤ 109) rectangle with 2 × 1 dominoes? For the answer would be very big, output the answer modulo M (0 < M ≤ 105).

Input

Input consists of several test cases followed by a line containing double 0. Each test case consists of two integers, N and M, respectively.

Output

For each test case, output the answer modules M.

Sample Input

1 100003 100005 100000 0

Sample Output

11195

Source

POJ Monthly--2007.10.06, Dagger

  • 递推公式及矩阵,快速幂加速
  • f[n]=f[n-1]+5*f[n-2]+f[n-3]-f[n-4];LL a[4][4]={    {11, 5, 1, 1},    { 0, 0, 0, 0},    { 0, 0, 0, 0},    { 0, 0, 0, 0}   },   c[4][4]={    { 1, 1, 0, 0},    { 5, 0, 1, 0},    { 1, 0, 0, 1},    {-1, 0, 0, 0}   };

#include <iostream>#include <string>#include <cstdio>#include <cstring>#include <algorithm>#include <climits>#include <cmath>#include <vector>#include <queue>#include <stack>#include <set>#include <map>using namespace std;typedef long long           LL ;typedef unsigned long long ULL ;const int    maxn = 1000 + 10  ;const int    inf  = 0x3f3f3f3f ;const int    npos = -1         ;const int    mod  = 1e9 + 7    ;const int    mxx  = 100 + 5    ;const double eps  = 1e-6       ;LL m;struct Matrix{    LL a[4][4];    Matrix operator * (const Matrix B){        Matrix C;        memset(&C,0,sizeof(C));        for(int k=0;k<4;k++)            for(int i=0;i<4;i++)                if(a[i][k])                    for(int j=0;j<4;j++)                        if(B.a[k][j])                            C.a[i][j]=((C.a[i][j] + (a[i][k]*B.a[k][j])%m)%m + m*2)%m;        return C;    }};LL a[4][4]={    {11, 5, 1, 1},    { 0, 0, 0, 0},    { 0, 0, 0, 0},    { 0, 0, 0, 0}   },   c[4][4]={    { 1, 1, 0, 0},    { 5, 0, 1, 0},    { 1, 0, 0, 1},    {-1, 0, 0, 0}   };LL cal(int k){    if(k>0){        Matrix e, f;        for(int i=0;i<4;i++)            for(int j=0;j<4;j++){                e.a[i][j]=a[i][j];                f.a[i][j]=c[i][j];            }        while(k){            if(1&k){                e=e*f;            }            f=f*f;            k>>=1;        }        return e.a[0][0]%m;    }else{        return a[0][-k]%m;    }}int n;int main(){    // freopen("in.txt","r",stdin);    // freopen("out.txt","w",stdout);    while((~scanf("%d %lld",&n,&m)) && n>0){        printf("%lld\n",cal(n-3));    }    return 0;}