题目描述

现有一个n 行m 列的棋盘,一只马欲从棋盘的左上角跳到右下角。每一步它向右跳奇数列,且跳到本行或相邻行。跳越期间,马不能离开棋盘。试求跳法种数mod 30011。

输入输出格式

输入格式:

仅有一行,包含两个正整数n, m,表示棋盘的规模。

输出格式:

仅有一行,包含一个整数,即跳法种数mod 30011。

输入输出样例

输入样例#1:

3 5

输出样例#1:

10

说明

对于10%的数据,1 ≤ n ≤ 10,2 ≤ m ≤ 10;

对于50%的数据,1 ≤ n ≤ 10,2 ≤ m ≤ 10^5;

对于80%的数据,1 ≤ n ≤ 10,2 ≤ m ≤ 10^9;

对于100%的数据,1 ≤ n ≤ 50,2 ≤ m ≤ 10^9。


题解

好久没写矩乘有点忘了

但是这种不难的题还是可以写出来的==

DP式子显然\(f[i][j] = (Sum[i-1][j]+Sum[i-1][j-1]+Sum[i-1][j+1])\)

那个\(Sum[i][j]\)表示的是第j行前i列的前缀和

然后这样不好做矩乘

可以用\(f[i][j]\)表示第j行前i列的前缀和

然后就是\(f[i][j] = f[i-2][j] + f[i-1][j] + f[i-1][j-1] + f[i-1][j+1]\)

但是这是个前缀和

所以\(Ans=f[m-1][n]+f[m-1][n-1]\)

这样就可以矩乘了

构造一个\((1 , n*2)\)的初始矩阵

前n个表示的是当前列的每一行的\(f[][]\)

后n个表示的是当前列的上一列的每一行的\(f[][]\)

然后转移矩阵就肥肠简单了

只需要把要转移的位置补上1就可以了

代码

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
const int N = 105 ;
const int mod = 30011 ;
using namespace std ;
int n , m , E ;
int t[N][N] , Ans ;
struct Matrix {
int f[N][N] ;
inline Matrix () { memset(f , 0 , sizeof(f)) ; }
inline void Start() { for(int i = 1 ; i <= E ; i ++) f[i][i] = 1 ; }
inline friend Matrix operator * (Matrix a , Matrix b) {
Matrix temp ;
for(int i = 1 ; i <= E ; i ++)
for(int j = 1 ; j <= E ; j ++)
for(int k = 1 ; k <= E ; k ++)
temp.f[i][j] = (temp.f[i][j] + a.f[i][k] * b.f[k][j]) % mod ;
return temp ;
}
} st , b , Now ; inline Matrix Fpw(Matrix Base , int k) {
Matrix temp ; temp.Start() ;
while(k) {
if(k & 1) temp = temp * Base ;
Base = Base * Base ; k >>= 1 ;
}
return temp ;
}
int main() {
cin >> n >> m ; t[1][1] = 1 ; E = (n << 1) ;
for(int i = 1 ; i <= n ; i ++) t[2][i] = (t[1][i] + t[1][i - 1] + t[1][i + 1]) % mod ;
if(m <= 3) { Ans = (t[m - 1][n] + t[m - 1][n - 1]) % mod ; printf("%d\n",Ans) ; return 0 ; }
for(int i = 1 ; i <= n ; i ++) st.f[1][i] = t[2][i] ;
for(int i = n + 1 ; i <= E ; i ++) st.f[1][i] = t[1][i - n] ;
for(int i = 1 ; i <= n ; i ++) {
b.f[i][i] = 1 ;
if(i != 1) b.f[i - 1][i] = 1 ;
if(i != n) b.f[i + 1][i] = 1 ;
b.f[i + n][i] = 1 ;
}
for(int i = n + 1 ; i <= E ; i ++) b.f[i - n][i] = 1 ;
Now = Fpw(b , m - 3) ; st = st * Now ;
Ans = (st.f[1][n] + st.f[1][n - 1]) % mod ;
cout << Ans << endl ;
return 0 ;
}

[SHOI2013]超级跳马的更多相关文章

  1. [BZOJ 4417][Shoi2013]超级跳马

    4417: [Shoi2013]超级跳马 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 379  Solved: 230[Submit][Status ...

  2. 洛谷 P3990 [SHOI2013]超级跳马 解题报告

    P3990 [SHOI2013]超级跳马 题目描述 现有一个\(n\) 行 \(m\) 列的棋盘,一只马欲从棋盘的左上角跳到右下角.每一步它向右跳奇数列,且跳到本行或相邻行.跳越期间,马不能离开棋盘. ...

  3. [题解][SHOI2013]超级跳马 动态规划/递推式/矩阵快速幂优化

    这道题... 让我见识了纪中的强大 这道题是来纪中第二天(7.2)做的,这么晚写题解是因为 我去学矩阵乘法啦啦啦啦啦对矩阵乘法一窍不通的童鞋戳链接啦 层层递推会TLE,正解矩阵快速幂 首先题意就是给你 ...

  4. BZOJ4417: [Shoi2013]超级跳马

    Description 现有一个n行m列的棋盘,一只马欲从棋盘的左上角跳到右下角.每一步它向右跳奇数列,且跳到本行或相邻行.跳越期间,马不能离开棋盘.例如,当n = 3, m = 10时,下图是一种可 ...

  5. 【BZOJ4417】: [Shoi2013]超级跳马

    题目链接: 传送. 题解: 矩阵快速幂优化DP. 先考虑$nm^2$DP,设$f_{(i,j)}$表示从$1,1$到$i,j$的方案,显然这个方程和奇偶性有关,我们考虑某列的$i$同奇偶性的转移和奇偶 ...

  6. Luogu P3990 [SHOI2013]超级跳马

    这道题还是一道比较不可做的矩阵题 首先我们先YY一个递推的算法:令f[i][j]表示走到第i行第j列时的方案数,那么有以下转移: f[i][j]=f[i-1][j-2*k+1]+f[i+1][j-2* ...

  7. 【bzoj4417】[Shoi2013]超级跳马 矩阵乘法

    题目描述 现有一个n行m列的棋盘,一只马欲从棋盘的左上角跳到右下角.每一步它向右跳奇数列,且跳到本行或相邻行.跳越期间,马不能离开棋盘.例如,当n = 3, m = 10时,下图是一种可行的跳法.   ...

  8. P3990 [SHOI2013]超级跳马

    传送门 首先不难设\(f[i][j]\)表示跳到\((i,j)\)的方案数,那么不难得到如下转移 \[f[i][j]=\sum\limits_{k=1}^{\frac n2}f[i-2k+1][j-1 ...

  9. BZOJ 4417 Luogu P3990 [SHOI2013]超级跳马 (DP、矩阵乘法)

    题目链接: (bzoj) https://www.lydsy.com/JudgeOnline/problem.php?id=4417 (luogu)https://www.luogu.org/prob ...

随机推荐

  1. 洛谷P1186 玛丽卡

    题目描述 麦克找了个新女朋友,玛丽卡对他非常恼火并伺机报复. 因为她和他们不住在同一个城市,因此她开始准备她的长途旅行. 在这个国家中每两个城市之间最多只有一条路相通,并且我们知道从一个城市到另一个城 ...

  2. 2017-10-02-afternoon

    T1 最大值(max) Time Limit:1000ms   Memory Limit:128MB 题目描述 LYK有一本书,上面有很多有趣的OI问题.今天LYK看到了这么一道题目: 这里有一个长度 ...

  3. MongoDB小结07 - update【$addToSet & $each】

    用$addToSet更新可以避免重复,将它与$each组合起来,可以一次性添加多条(就算后添加的值已存在也没有关系) db.user.update({"name":"co ...

  4. NTKO在线office控件使用实例

    目录 1. NTKO在线office控件使用实例 1.1. 基础介绍 1.2. 基本原理 1.3. 实例 1.3.1. 打开.保存部分代码 1.3.2. 动态设值 1. NTKO在线office控件使 ...

  5. 条款一:仔细区别pointers 和 reference

    1.一个reference必须总代表某个对象,没有所谓的null reference.如果你有一个变量,其目的是用来指向(代表)另一个对象,但是也有可能它不指向(代表)另一个对象,那么应该使用poin ...

  6. 玩转iOS开发 - 消息推送

    消息推送

  7. Python学习系列之反射

    反射的定义 根据字符串的形式去某个对象中操作成员 根据字符串的形式去某个对象中寻找成员 根据字符串的形式去某个对象中设置成员 根据字符串的形式去某个对象中删除成员 根据字符串的形式去某个对象中判断成员 ...

  8. 文件权限的获取,cmd命令:Takeown

    takeown /f * /a /r /d y #强制将当前目录下的所有文件及文件夹.子文件夹下的所有者更改为管理员组(administrators)命令: cacls d:documents*.* ...

  9. C#——await与async实现多线程异步编程

    曾经,我们也许用过Thread.在主线程运行的时候.新开还有一个新线程,来运行新方法. 今天看别人发给我的一段代码的时候发现了一个不认识的await,可是又感觉非常熟悉的样子,感觉是线程那块儿的东西, ...

  10. Jmeter技巧

    Jmeter参数化的4种方法 用Jmeter测试时包含两种情况的参数,一种是在url中,一种是请求中需要发送的参数. URL中的参数,如:http://blog.da-fang.com/index.p ...