hdu5673 Robot 卡特兰数+组合数学+线性筛逆元

Robot

Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 483    Accepted Submission(s): 244

Problem Description

There
is a robot on the origin point of an axis.Every second, the robot can
move right one unit length or do nothing.If the robot is
on the
right of origin point,it can also move left one unit length.A route is a
series of movement. How many different routes there are
that after n seconds the robot is still located on the origin point?
The answer may be large. Please output the answer modulo 1,000,000,007

Input

There are multiple test cases. The first line of input contains an integer T(1≤T≤100) indicating the number of test cases. For each test case:

The only line contains one integer n(1≤n≤1,000,000).

Output

For each test case, output one integer.

Sample Input

3
1
2
4

Sample Output

1
2
9

Source

BestCoder Round #81 (div.2)

/**
题目:Robot
链接:http://acm.hdu.edu.cn/showproblem.php?pid=5673
题意:在x轴上,机器人从原点出发,如果它在原点,他只可以向右走一格,或者停留原处(表明机器人不可以到负数坐标的位置);
如果不在原点,它可以向右,向左,停留原地;每次操作花费1秒;问n秒后,机器人回到原点的行走方法数;

思路:
过程中一定是向右走的步数>=向左走的步数,最后是相等。想到了什么?括号匹配? 求方法数->卡特兰数。
现在还有一个是停在原地。设停在原地为y次。向右走为x次,那么向左走也为x次。
2*x+y==n;
那么确定了x,y。方法数:C(n,y)*h(x). 很显然;

*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int mod=1e9+7;
const int maxn=1e6+5;
LL h[maxn], c[maxn], inv[maxn];
void init()
{
    inv[1] = 1;
    for(int i = 2; i < maxn; i++){
        inv[i] = (mod-mod/i)*inv[mod%i]%mod;
    }
    h[0] = 1;
    for(int i = 1; i < maxn; i++){
        h[i] = (4*i-2)*h[i-1]%mod*inv[i+1]%mod;
    }
}
int main()
{
    init();
    int T;
    int n;
    cin>>T;
    while(T--)
    {
        scanf("%d",&n);
        LL ans = 0;
        c[0] = 1;
        for(int i = 1; i <= n; i++){///c(n,i);
            c[i] = (n-i+1)*c[i-1]%mod*inv[i]%mod;
        }
        for(int x = 0; x*2<=n; x++){
            int y = n-2*x;
            ans = (ans+c[y]*h[x]%mod)%mod;
        }
        printf("%lld\n",ans);
    }
    return 0;
}
时间: 2024-10-25 00:13:57

hdu5673 Robot 卡特兰数+组合数学+线性筛逆元的相关文章

hdu5673 Robot 卡特兰数 / 默慈金数

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5673 分析: 这道题是一道裸的默慈金数,比较容易想到的是用卡特兰数来做.不了解的可以先学习一下. 卡特兰数:http://www.cnblogs.com/yaoyueduzhen/p/5456490.html 默慈金数:http://www.cnblogs.com/yaoyueduzhen/p/5456530.html 记路径长度为nn,那么机器人最多向右走⌊?n/2??⌋步并向左走⌊?n/2??⌋

uva 1478 - Delta Wave(递推+大数+卡特兰数+组合数学)

题目链接:uva 1478 - Delta Wave 题目大意:对于每个位置来说,可以向上,水平,向下,坐标不能位负,每次上下移动最多为1, 给定n问说有多少种不同的图.结果对10100取模. 解题思路:因为最后都要落回y=0的位置,所以上升的次数和下降的次数是相同的,并且上升下降的关系满足出栈入栈的关系.即卡特兰数. 所以每次枚举i,表示有i个上升,i个下降,用组合数学枚举出位置,然后累加求和. C(2?in)?f(i)=C(2?i?2n)?f(i?1)?(n?2?i+1)?(n?2?i+2)

【BZOJ3823】【East!模拟赛_Round5T1】定情信物 推公式+线性筛逆元(推公式法比出题人简)

题解1: 我们定义点为0维元素.线为1维元素.面为2维元素-- 既然一个低维超方体在对应新轴上平移得到高一维的超方体,比如二维超方体为一个面,然后沿新出现的z轴拓展,那么一个低维元素就会增加一维变成高一维的元素,比如点变成线.线变成面.面变成体-- 这样就有一个推式: 高维元素会由第一维的元素衍生.同维元素复制保留, 也就是一个超方体升维之后,高维超方体第i维元素的数量将是原超方体第i维的数量*2+(i-1)维的数量. 然后经过鬼畜的推导/撞大运的找规律,可以得到一个组合数公式, 最后加个线性筛

hdu 5673 Robot 卡特兰数+逆元

Robot Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Problem Description There is a robot on the origin point of an axis.Every second, the robot can move right one unit length or do nothing.If the robot is on the

HDU 5673 Robot 卡特兰数

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5673 题目描述: 一个人从原点开始向右走, 要求N秒后回到原点, 且过程中不能到负半轴, 人有两种操作, 走动或者停止, 问总共有多少种方案? 解题思路: 类似于括号匹配问题, 和那个我去年这个时候接触到的最裸的不能越过对角线的正方形走到对角问题, 卡特兰数, 从2开始枚举走动步数, 然后剩下的就是不动的步数, 用不动的步数做个填充就可以了, 设计到取模, 需要逆元 代码: #include <i

HDU5673 Robot 默慈金数

分析: 注:然后学了一发线性筛逆元的姿势 链接:http://blog.miskcoo.com/2014/09/linear-find-all-invert #include<iostream> #include<algorithm> #include<set> #include<vector> #include<queue> #include<cstdlib> #include<cstdio> #include<c

线性筛合集

迟到的线性筛合集. 1.线性筛质数. 这个不讲了大家都会.不过他是下面的基础.注意每个数都是被最小质因子筛去的. 2.线性筛逆元. 这个有两种做法.第一种是质数直接用费马小定理,然后根据逆元是完全积性函数直接乘起来. 第二种直接线性递推.设\(p = ki + b\),则有\(ki + b \equiv 0 (mod\ p),b = p\ \%\ i,k = \lfloor\frac{p}{i}\rfloor\) \(b \equiv -ki (mod\ p)\)两边同乘\(inv_b,inv_

快速幂+线性筛

求 Σik  (i=1...n) mod m 0 < m ≤ 3 × 10^6 , n, k ≤ 10^18 首先想到只需要i只需要循环到m,后面的值可以通过前缀和算出 所以问题变为了 Σik  (i=1...m) mod m 可以看出直接快速幂会超时 那么只需要找出1~m中质数的k次方,其他的数用线性筛算出值 因为1~m中大约有m/(Inm)个质数 一次快速幂所用的复杂度为log级别 所以总复杂度大约是O(m)级别的 灵活运用区间内素数的分布 强得一批

HDU 5673 Robot(卡特兰数)

题目链接:点击打开链接 思路:卡特兰数可以用来求括号序列的个数, 用了组合数学的知识. 该题其实就等价于求一个括号序列的个数, 因为满足任意时刻, 向右的步数大于等于向左的步数. 但是该题还有停止不动的情况, 所以我们不妨枚举向右的步数, 然后求出括号序列的组合数, 然后剩下的就是停止不动的步数, 用组合数插空即可. 另外, 除法取模要取逆元, 我们可以线性预处理出所有逆元. 细节参见代码: #include<cstdio> #include<cstring> #include&l