【bzoj4417】[Shoi2013]超级跳马 【矩阵快速幂】
题目链接 
题解:我们设为跳到的位置的方案总数。 
则显然 
这样做显然会超时。 
我们再设为分别跳到i这一行,距离j奇数格的所有格子的方案总数。 
则 
 
然后矩阵快速幂加速计算即可。 
我的矩阵大小是3*n的,还被xsy卡常了,所以以后矩阵乘法我再也不写在结构体里面了= = 
代码:
#include<cstdio>
#include<cstring>
const int mod=30011;
int n,m,res[155][155],base[155][155],tmp[155][155];
void times(int a[][155],int b[][155]){
    memset(tmp,0,sizeof(tmp));
    for(int i=1;i<=3*n;i++){
        for(int j=1;j<=3*n;j++){
            for(int k=1;k<=3*n;k++){
                tmp[i][j]+=a[i][k]*b[k][j]%mod;
                tmp[i][j]=tmp[i][j]>=mod?tmp[i][j]-mod:tmp[i][j];
            }
        }
    }
    for(int i=1;i<=3*n;i++){
        for(int j=1;j<=3*n;j++){
            a[i][j]=tmp[i][j];
        }
    }
}
int main(){
    scanf("%d%d",&n,&m);
    if(m==1){
        if(n==1){
            puts("1");
        }else{
            puts("0");
        }
        return 0;
    }
    res[1][n+1]=1;
    for(int i=1;i<=n;i++){
        base[2*n+i][i]=1;
        if(i-1>0){
            base[i-1][n+i]=1;
            base[n+i-1][n+i]=1;
        }
        base[i][n+i]=1;
        base[n+i][n+i]=1;
        base[i][2*n+i]=1;
        base[n+i][2*n+i]=1;
        if(i+1<=n){
            base[i+1][n+i]=1;
            base[n+i+1][n+i]=1;
        }
    }
    m--;
    while(m){
        if(m&1){
            times(res,base);
        }
        m>>=1;
        times(base,base);
    }
    printf("%d\n",res[1][2*n]);
    return 0;
} 
                    
                
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号