Robot
Accepts: 38
Submissions: 146
Time Limit: 12000/6000 MS (Java/Others)
Memory Limit: 65536/65536 K (Java/Others)
问题描述
有一个机器人位于坐标原点上。每秒钟机器人都可以向右移到一个单位距离,或者在原地不动。如果机器人的当前位置在原点右侧,它同样可以 向左移动单位距离。一系列的移动(左移,右移,原地不动)定义为一个路径。问有多少种不同的路径,使得nnn秒后机器人仍然位于坐标原点? 答案可能很大,只需输出答案对1,000,000,0071,000,000,0071,000,000,007的模。
输入描述
输入包含多组数据. 第一行有一个整数T(1≤T≤100)T (1\leq T\leq 100)T(1≤T≤100), 表示测试数据的组数. 对于每组数据: 输入一个整数 n(1≤n≤1,000,000)n (1\leq n\leq 1,000,000)n(1≤n≤1,000,000)。
输出描述
对于每组数据,输出一个整数
输入样例
3 1 2 4
输出样例
1 2 9
BC题解:
数论:带模除法/逆元/费马小定理参考:
https://www.huangwenchao.com.cn/2014/05/mod-div.html
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cstring>
#include <string>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <stack>
using namespace std;
const int MAXN = 1e6+7;
const long long MOD = 1e9+7;
long long cat[MAXN];
long long inv[MAXN];
long long A[MAXN],A_inv[MAXN];
long long get_INV(long long a)
{
if(a<MAXN-1)return inv[a];
return (long long)get_INV(MOD%a)*(MOD-MOD/a)%MOD;
}
void get_inverse()
{
inv[1]=1;
for(int i=2; i<MAXN; ++i)
inv[i]=inv[MOD%i]*(MOD-MOD/i)%MOD;
}
void get_Catalan()
{
cat[0]=cat[1]=1;
for(int i=2; i<MAXN; ++i)
cat[i]=(((long long)cat[i-1]*(4*i-2)%MOD)*inv[i+1])%MOD;
}
void get_Combination_number()
{
A[0]=1;
A_inv[0]=1;
for(int i=1; i<MAXN; ++i)
{
A[i]=(long long)A[i-1]*i%MOD;
A_inv[i]=get_INV(A[i]);
}
}
int main()
{
int T;
get_inverse();//逆元打表
get_Catalan();//卡特兰数打表
get_Combination_number();//组合数打表
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d",&n);
long long ANS=0;
for(int i=0; i<=n/2; ++i)
{
ANS+=(((A[n]*A_inv[2*i]%MOD)*A_inv[n-2*i])%MOD*cat[i])%MOD;
ANS%=MOD;
}
printf("%I64d\n",ANS);
}
return 0;
}