BZOJ 4417 超级跳马
Posted ziliuziliu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ 4417 超级跳马相关的知识,希望对你有一定的参考价值。
dp前缀和优化+矩阵快速幂。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxn 110 #define mod 30011 using namespace std; struct matrix { int a[maxn][maxn]; }a,b; int n,m,dp[maxn][5]; void get_table() { for (int i=1;i<=n;i++) a.a[1][i]=dp[i][1]; for (int i=1;i<=n;i++) a.a[1][n+i]=dp[i][2]; for (int i=1;i<=n;i++) b.a[i+n][i]=1; for (int i=1;i<=n;i++) b.a[i][n+i]=b.a[max(n+i-1,n+1)][n+i]=b.a[n+i][n+i]=b.a[min(n+i+1,2*n)][n+i]=1; } matrix mul(matrix a,matrix b) { matrix c; for (int i=1;i<=2*n;i++) for (int j=1;j<=2*n;j++) c.a[i][j]=0; for (int i=1;i<=2*n;i++) for (int j=1;j<=2*n;j++) for (int k=1;k<=2*n;k++) c.a[i][j]=(c.a[i][j]+(a.a[i][k]*b.a[k][j])%mod)%mod; return c; } void f_pow(int y) { matrix base=b; while (y) { if (y&1) a=mul(a,base); base=mul(base,base); y>>=1; } } int main() { scanf("%d%d",&n,&m); dp[1][1]=1; for (int i=1;i<=n;i++) dp[i][2]=(dp[i-1][1]+dp[i][1]+dp[i+1][1])%mod; for (int i=1;i<=n;i++) dp[i][3]=(dp[i-1][2]+dp[i][2]+dp[i+1][2]+dp[i][1])%mod; get_table(); if (m==1) {if (n<=2) printf("1\n");else printf("0\n");return 0;} else if (m<=3) {printf("%d\n",(dp[n][m]-dp[n][m-2]+mod)%mod);return 0;} f_pow(m-3); int ret1,ret2; ret1=a.a[1][n];a=mul(a,b);ret2=a.a[1][2*n]; printf("%d\n",(ret2-ret1+mod)%mod); return 0; }
以上是关于BZOJ 4417 超级跳马的主要内容,如果未能解决你的问题,请参考以下文章