SJTU SCPC Monthly Oct.2013 Problem E. back
【题目描述】
爱丽丝的二大爷突然来到爱丽丝的家中,把他刚出生三个月的宝宝交给了爱丽丝,她不得不总是花些时间来照顾宝宝。而爱丽丝是一个喜欢散步的人,她想在附近走走。这让爱丽丝痛苦不堪。
爱丽丝生活在一个类似数轴一样的街上,数轴的每个单位点上都是一个街区,每个单位时间的开始,爱丽丝可以瞬间向东走一个街区,或者瞬间向西走一个街区,并在这个街区停留一个单位的时间,这条街向东向西都没有尽头,爱丽丝现在正在自己的家中。
距离二大爷回来把孩子带走还有n个单位的时间,爱丽丝必须在距离上次相隔不超过m的时间内回到家中检查宝宝是否需要换纸尿裤,否则宝宝会一直大哭,直到二大爷的到来。
请问爱丽丝有多少种不同的、确保宝宝不会大哭散步过程。
两个散步过程不同当且仅当存在同一时间爱丽丝走向了不同的方向,注意每个单位时间的开始,爱丽丝必须选择向东走或向西走,不可停留在原地,而且在第n个时间结束,爱丽丝必须回到家中。
【输入格式】
输入入的第一行包含一个整数T,表示数据的组数。 接下来每组数据的第一行包括两个整数n和m,意义如题目描述中所述。
【输出格式】
输出T行,每行包括一个整数,表示爱丽丝可能的不同的散步过程,由于结果较大,请输出与1000000007取模的结果。
【样例输入】
2
4 2
10 6
【样例输出】
4
184
【数据范围】
2<=n<=10^9。
2<=m<=100。
n和m均为偶数。
1 #pragma comment(linker, "/STACK:1024000000,1024000000") 2 #include <map> 3 #include <queue> 4 #include <vector> 5 #include <string> 6 #include <cstdio> 7 #include <cstring> 8 #include <iostream> 9 #include <algorithm> 10 using namespace std; 11 #define maxn 105 12 #define mod 1000000007 13 #define FF(i,n) for(int i=0;i<n/2;i++) 14 #define ll long long 15 #define INF 0x7fffffff 16 ll f[maxn][maxn]; 17 int n, m; 18 struct mat { ll m[105][105]; }; 19 mat Mul(mat a, mat b){ 20 mat res; 21 FF(i, n)FF(j, n)res.m[i][j]=0; 22 FF(i, n)FF(j, n)FF(k, n)res.m[i][j] = (res.m[i][j] + a.m[i][k] * b.m[k][j] % mod) % mod; 23 return res; 24 } 25 mat Pow(mat a, ll b){ 26 mat res; 27 FF(i, n)FF(j, n)res.m[i][j] = (i == j); 28 while (b){ 29 if (b & 1)res = Mul(res, a); 30 a = Mul(a, a); 31 b >>= 1; 32 } 33 return res; 34 } 35 ll dfs(int x, int y){ 36 if (f[x][y+m] != -1)return f[x][y+m]; 37 if (x == 1){ 38 if (y == 1 || y == -1)return f[x][y + m] = 1; 39 return f[x][y + m] = 0; 40 } 41 ll res = 0; 42 if (y+1!=0)res = (res+dfs(x - 1, y + 1))%mod; 43 if (y-1!=0)res = (res+dfs(x - 1, y - 1))%mod; 44 return f[x][y + m] = res; 45 } 46 int main(){ 47 int cas = 1; 48 memset(f, -1, sizeof f); 49 for (int i = 0; i < maxn; i++)dfs(i,0); 50 int t; 51 scanf("%d", &t); 52 while (t--){ 53 mat A; 54 memset(A.m, 0, sizeof A.m); 55 scanf("%d%d", &m, &n); 56 for (int i = 0; i < n/2; i++){ 57 A.m[i + 1][i] = 1; 58 A.m[0][i] = f[(i+1)*2][0]; 59 } 60 A = Pow(A, m / 2); 61 printf("%lld\n", A.m[0][0]); 62 } 63 return 0; 64 }
浙公网安备 33010602011771号