# bzoj4417 [Shoi2013]超级跳马

【题解】

f[i,j]=Σg[1..i-1,j]+Σg[1..i-1,j-1]+Σg[1..i-1,j+1]

g[i,j]=Σf[1..i,j]+Σf[1..i,j-1]+Σf[1..i,j+1]

f[i,j]=f[i-1,j]+g[i-1,j]+g[i-1,j-1]+g[i-1,j+1]

g[i,j]=g[i-1,j]+f[i,j]+f[i,j-1]+f[i,j+1]

f[i,1], f[i,2], ..., f[i,n], g[i,1], g[i,2], ..., g[i,n]

# include <stdio.h>
# include <assert.h>
# include <string.h>
# include <iostream>
# include <algorithm>
// # include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const int M = 150 + 10;
const int mod = 30011;

# define RG register
# define ST static

struct matrix {
int a[M][M], n, m;
inline void set(int _n, int _m) {
n = _n, m = _m;
memset(a, 0, sizeof a);
}
friend matrix operator *(matrix a, matrix b) {
matrix c; c.set(a.n, b.m);
assert(a.m == b.n);
for (int i=1; i<=c.n; ++i)
for (int j=1; j<=c.m; ++j)
for (int k=1; k<=a.m; ++k)
c.a[i][j] = (c.a[i][j] + a.a[i][k] * b.a[k][j]) % mod;
return c;
}
friend matrix operator ^(matrix a, int b) {
matrix c; c.set(a.n, a.m);
assert(a.n == a.m);
for (int i=1; i<=c.n; ++i) c.a[i][i] = 1;
while(b) {
if(b&1) c = c*a;
a = a*a;
b >>= 1;
}
return c;
}
inline void prt() {
for (int i=1; i<=n; ++i, cout << endl)
for (int j=1; j<=m; ++j) cout << a[i][j] << " ";
}
}A, T1, T2, T, B;

int n, m;

int main() {
cin >> n >> m;
T1.set(n+n, n+n), T2.set(n+n, n+n);
for (int i=1; i<=n; ++i) {
T1.a[i][i] = 1;
T2.a[i][i] = 1;
T1.a[i+n][i] = 1;
T2.a[i][i+n] = 1;
if(i != 1) {
T1.a[i-1+n][i] = 1;
T2.a[i-1][i+n] = 1;
}
if(i != n) {
T1.a[i+1+n][i] = 1;
T2.a[i+1][i+n] = 1;
}
T1.a[i+n][i+n] = 1;
T2.a[i+n][i+n] = 1;
}
T = T1*T2;
A.set(1, n+n);
A.a[1][1] = 1;
A.a[1][1+n] = 1;
if(n != 1) A.a[1][1+n+1] =1;
int times = (m-1)/2;
if(times == 0) {
if(m == 1) cout << A.a[1][n];
else cout << A.a[1][n+n];
return 0;
}
--times;
A = A * (T^times);
B = A * T;
if(m&1) cout << ((B.a[1][n] - A.a[1][n]) % mod + mod) % mod;
else cout << ((B.a[1][n+n] - A.a[1][n+n]) % mod + mod) % mod;
return 0;
}
View Code

posted @ 2017-05-30 22:38  Galaxies  阅读(2040)  评论(0编辑  收藏  举报