UESTC1610 黑红梅方

题意:一行有n个扑克牌,每一个扑克牌有四种颜色,问有几种扑克牌,满足连续四个不相等

题解:状态压缩+递推+矩阵快速幂,不过状态很多,不能直接写,这里分为5种状态

#include <bits/stdc++.h>
#define maxn 5
const long long mod = (1e9+9);
using namespace std;
struct mat{
    long long m[maxn][maxn], len;
    mat(){memset(m, 0, sizeof(m));len=maxn;}
    mat friend operator*(mat a,mat b){
        mat d;
        for(int i=0;i<a.len;i++)
            for(int j=0;j<b.len;j++)
                for(int k=0;k<b.len;k++)
                d.m[i][j] = (d.m[i][j]%mod+(a.m[i][k]*b.m[k][j])%mod)%mod;
        return d;
    }
};
mat f(mat x,long long num){
    mat t;
    for(int i=0;i<t.len;i++) t.m[i][i] = 1;
    while(num){
        if(num&1) t = t*x;
        x = x*x;
        num >>= 1;
    }
    return t;
}
long long ff(long long x,long long t,long long m){
    long long ans=1;
    while(t){
        if(t&1) ans = ans*x%m;
        x = x*x%m;
        t >>= 1;
    }
    return ans;
}
int main(){
    long long  n;
    mat fi, t;
    int tt[5][5]={
        1,0,3,0,0,
        0,1,0,1,2,
        0,1,0,1,2,
        1,0,3,0,0,
        0,1,0,1,1
    };
    fi.m[0][0] = 4;
    fi.m[0][1] = 12;
    fi.m[0][2] = 12;
    fi.m[0][3] = 12;
    fi.m[0][4] = 24;
    for(int i=0;i<5;i++)
        for(int j=0;j<5;j++)
        t.m[i][j] = tt[i][j];
    cin>>n;
    fi = fi*f(t, n-3);
    cout<<((ff(4, n, mod)-fi.m[0][0]-fi.m[0][1]-fi.m[0][2]-fi.m[0][3]-fi.m[0][4])%mod+mod)%mod<<endl;
    return 0;
}

 

posted on 2017-07-22 15:58  2855669158  阅读(203)  评论(0编辑  收藏  举报

导航