# BZOJ4417: [Shoi2013]超级跳马

3 5

10

## HINT

#include<cstdio>
#include<cctype>
#include<queue>
#include<cmath>
#include<cstring>
#include<algorithm>
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define dwn(i,s,t) for(int i=s;i>=t;i--)
#define ren for(int i=first[x];i;i=next[i])
using namespace std;
const int BufferSize=1<<16;
inline char Getchar() {
}
}
int x=0,f=1;char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
for(;isdigit(c);c=getchar()) x=x*10+c-'0';
return x*f;
}
typedef long long ll;
const int mod=30011;
const int maxn=110;
int N;
struct Matrix {
ll A[maxn][maxn];
Matrix operator * (const Matrix& b) const {
Matrix c;
rep(i,1,N) rep(j,1,N) {
c.A[i][j]=0;
rep(k,1,N) c.A[i][j]+=A[i][k]*b.A[k][j];
c.A[i][j]%=mod;
}
return c;
}
};
void pow(Matrix& ans,int n) {
Matrix t;t=ans;n--;
while(n) {
if(n&1) ans=ans*t;
t=t*t;n>>=1;
}
}
int main() {
Matrix ans;N=n*2;
memset(ans.A,0,sizeof(ans.A));
rep(i,1,n) ans.A[i][i+n]=1;
rep(i,n+1,2*n) {
ans.A[i][i-n]=ans.A[i-n][i-n]=1;
if(i-n>1) ans.A[i-n-1][i-n]=1;
if(i-n<n) ans.A[i-n+1][i-n]=1;
}
pow(ans,m-1);
printf("%lld\n",(ans.A[N][1]+(n>1?ans.A[N-1][1]:0))%mod);
return 0;
}
View Code
posted @ 2016-03-10 17:09  wzj_is_a_juruo  阅读(246)  评论(0编辑  收藏  举报