题目链接:http://acm.uestc.edu.cn/#/problem/show/1610
解法:
卿式扑克序列?
出现一组有连续4张牌均不同的序列
不好计算,怎么办?
可以计算出没有一组连续4张牌均不同的情况,用总情况减去没有一组连续4张牌均不同的情况
我们来看 三张牌排成一排有哪些情况?
三张牌均相同 AAA dp1
前两张牌相同,第三张牌不同 AAB dp2
第一和第三张牌相同,第二张牌不同 ABA dp3
后两张牌相同,第一张牌不同 BAA dp4
三张牌均不相同 ABC dp5
我们设dpx[i]为前i张牌最后三张牌为第x种类型且不出现一组连续4张牌均不同的情况
可得以下方程:
dp1[i]=dp1[i-1]+dp4[i-1]
dp2[i]=3*dp1[i-1]+3*dp4[i-1]
dp3[i]=dp2[i-1]+dp3[i-1]+dp5[i-1]
dp4[i]=dp2[i-1]+dp3[i-1]+dp5[i-1]
dp5[i]=2*dp2[i-1]+2*dp3[i-1]+dp5[i-1]
初始值:dp1[3]=4 dp2[3]=12 dp3[3]=12 dp4[3]=12 dp5[3]=24
N=10^18 逗我呢?

矩阵快速幂!

(dp1[i],dp2[i],dp3[i],dp4[i],dp5[i])=(dp1[i-1],dp2[i-1],dp3[i-1],dp4[i-1],dp5[i-1])*

1001030030011010110102201

B(N)=B(3)*A^(N-3)
Matrix multiply(Matrix a,Matrix b) {}
void quickmat(long long k)
{
while(k)
{
if (k & 1) {res=multiply(res,origin);}
k>>=1;
origin=multiply(origin,origin);
}
}
res=dp1[n]+dp2[n]+dp3[n]+dp4[n]+dp5[n]
用普通快速幂算出4^n=tot,本题所求的答案ans=tot-res;注意取模的问题
算法复杂度:O(log N)
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL mod = 1e9+9;
LL powmod(LL a, LL n)
{
    LL res=1;
    while(n){
        if(n&1) res=(res%mod*a%mod)%mod;
        a=(a%mod*a%mod)%mod;
        n>>=1;
    }
    return res;
}
struct Matrix{
    LL a[5][5];
    void init(){
        memset(a,0,sizeof(a));
    }
    void init2(){
        memset(a,0,sizeof(a));
        for(int i=0; i<5; i++) a[i][i]=1;
    }
};
Matrix operator * (Matrix a, Matrix b){
    Matrix res;
    res.init();
    for(int i=0; i<5; i++){
        for(int j=0; j<5; j++){
            for(int k=0;k<5; k++){
                res.a[i][j]=(res.a[i][j]+(a.a[i][k]*b.a[k][j])%mod)%mod;
            }
        }
    }
    return res;
}
Matrix ksm(Matrix a, LL n){
    Matrix res;
    res.init2();
    while(n){
        if(n&1) res=res*a;
        a=a*a;
        n>>=1;
    }
    return res;
}
int main()
{
    LL n;
    scanf("%lld",&n);
    Matrix A,B;
    A.init();
    B.init();
    A.a[0][0]=1,A.a[0][1]=3,A.a[1][2]=1,A.a[1][3]=1,A.a[1][4]=2;
    A.a[2][2]=1;A.a[2][3]=1;A.a[2][4]=2;
    A.a[3][0]=1;A.a[3][1]=3;
    A.a[4][2]=1;A.a[4][3]=1;A.a[4][4]=1;
    B.a[0][0]=4;B.a[0][1]=12;B.a[0][2]=12;B.a[0][3]=12;B.a[0][4]=24;
    Matrix ans=ksm(A,n-3);
//    for(int i=0; i<5; i++){
//        for(int j=0; j<5; j++){
//            printf("%d ",ans.a[i][j]);
//        }
//        printf("\n");
//    }
    ans=B*ans;
//    for(int i=0; i<5; i++){
//        for(int j=0; j<5; j++){
//            printf("%d ",ans.a[i][j]);
//        }
//        printf("\n");
//    }
    LL ret = 0;
    for(int i=0; i<5; i++){
        ret=(ret+ans.a[0][i])%mod;
    }
    ret = (powmod(4,n)-ret+mod)%mod;
    if(ret<0) ret+=mod;
    printf("%lld\n", ret);
    return 0;
}