矩阵加速数列递推

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4973

ZOJ Problem Set - 3690 

Code

poj 3734 Blocks

f[i][a][b](a,b=0/1)表示长度为i的序列,红绿颜色的奇偶情况分别为a,b。递推公式比较好写,答案就是f[n][0][0],后两维也可以用一个两位二进制数表示。可以发现F[0]={1,1,1,1},所以写起来也比较简洁。其实实现上不需要体现出状态,全是矩阵乘。

#include <iostream>
#include <cstring>
using namespace std;

struct Matrix{

#define MAXN 4
#define MOD 10007

int  x,y;
long long  data[MAXN][MAXN];

struct CannotMultiply{};

Matrix(int _x=0,int _y=0):x(_x),y(_y){
    memset(data,0, sizeof(data));
  }
Matrix operator*(const  Matrix& rig)const {
    if(y!=rig.x)throw  CannotMultiply();
    Matrix res;
    res.x=x;
    res.y=rig.y;
    for (int  i=0;i<x;++i){
      for (int  j=0;j<rig.y;++j){
        for (int  k=0;k<y;++k){
          res.data[i][j] += data[i][k]*rig.data[k][j];
          res.data[i][j] %= MOD;
        }
      }
    }
    return res;
  }

};

Matrix pow(Matrix A,int n){
    Matrix res(A.x,A.y);
    for(int i=0;i<res.x;i++) res.data[i][i]=1;
    for(;n>0;n>>=1,A=A*A)
        if(n&1)
            res=res*A;
    return res;
}

int main()
{
    Matrix f(4,4);
    for(int i=0;i<4;i++)
        for(int j=0;j<4;j++)
            f.data[i][j]=1;
    for(int i=0;i<4;i++){
        f.data[i][i]  =2;
        f.data[i][3-i]=0;
    }

    int T;cin>>T;
    while(T--){
        int n;
        cin>>n;
        Matrix ans;
        ans=pow(f,n);
        cout<<ans.data[0][0]<<endl;
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/lijianlin1995/p/3448481.html