NC19833 地斗主(dp+矩阵快速幂)

经典填格子问题,这种题都是推出前面的情况后,再不重复的情况求出后面的递推式

因为本题次数大,因此考虑使用矩阵快速幂优化

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
const int N=30;
const int inf=0x3f3f3f3f;
int n,m;
struct node{
    int a[4][4];
    node(){
        memset(a,0,sizeof a);
    }
};
node operator *(node a,node b) {
    node tmp;
    for(int i=0;i<=3;i++) {
        for(int j=0;j<=3;j++) {
            for(int k=0;k<=3;k++) {
                tmp.a[i][j]=((ll)tmp.a[i][j]+(ll)a.a[i][k]*b.a[k][j]%m)%m;
            }
        }
    }
    return tmp;
}
node martix_pow(node s,ll b){
    int i;
    node tmp;
    for(i=0;i<4;i++){
        tmp.a[i][i]=1;
    }
    while(b){
        if(b&1)
            tmp=tmp*s;
        s=s*s;
        b>>=1;
    }
    return tmp;
}
int main(){
    ios::sync_with_stdio(false);
    int t;
    cin>>t;
    while(t--){
        cin>>n>>m;
        int a1,a2,a3,a4;
        a1=1,a2=5,a3=11,a4=36;
        if(n==1){
            cout<<a1<<endl;
            continue;
        }
        if(n==2){
            cout<<a2<<endl;
            continue;
        }
        if(n==3){
            cout<<a3<<endl;
            continue;
        }
        if(n==4){
            cout<<a4<<endl;
            continue;
        }
        node s,t;
        s.a[0][0]=a4,s.a[1][0]=a3,s.a[2][0]=a2,s.a[3][0]=a1;
        n-=4;
        t.a[0][0]=t.a[1][0]=t.a[2][1]=t.a[3][2]=t.a[0][2]=1;
        t.a[0][1]=5,t.a[0][3]=-1;
        t=martix_pow(t,n);
        s=t*s;
        cout<<(s.a[0][0]+m)%m<<endl;
    }
    return 0;

}
View Code

 

posted @ 2021-03-09 14:10  朝暮不思  阅读(54)  评论(0编辑  收藏  举报