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??⌋步。

      Ans(n)=∑C?(n,?2i)?? Catalan(i)

  其中 C(n,2i) 表示从n个物品中取2*i个的组合数,Catalan(n)表示第n个卡特兰数,0 <= i <= ⌊?n/2??⌋

  基于n的取值范围,此题可以预处理出1,000,001以内的乘法逆元、卡特兰数。

  每次询问,都可以递推组合数,或者提前一次性预处理好阶乘和阶乘的逆元得到组合数;累加组合数与相应卡特兰数的乘积,得到答案。

  事实上,Ans(n)是第n个默慈金数,利用递推公式可以快速求出。

卡特兰数代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstring>
 5
 6 using namespace std;
 7 const long long mod=1000000007;
 8 long long n;
 9 long long ans[1100000],ni[1100000];
10
11 long long power(long long a,long long n,long long m)
12 {
13     long long ans=1,tmp=a;
14     while(n)
15     {
16         if(n&1)
17             ans=ans*tmp%m;
18         tmp=tmp*tmp%m;
19         n=n>>1;
20     }
21     return ans%m;
22 }
23
24 void init()
25 {
26     ans[0]=1;
27     ans[1]=1;
28     for(long long i=1;i<=1000005;i++)
29         ni[i]=power(i,mod-2,mod)%mod;
30     for(long long i=2;i<=1000000;i++)
31         ans[i]=(4*i-2)%mod*ans[i-1]%mod*ni[i+1]%mod;
32 }
33
34 int main()
35 {
36     init();
37     int T;
38     scanf("%d",&T);
39     while(T--)
40     {
41         scanf("%lld",&n);
42         long long res=0,tmp=1;
43         for(long long  i=0;i*2<=n;i++)
44         {
45             res=(res+tmp*ans[i]%mod)%mod;
46             tmp=tmp*(n-2*i)%mod*(n-2*i-1)%mod*ni[2*i+1]%mod*ni[2*i+2]%mod;
47         }
48         cout<<res<<endl;
49     }
50     return 0;
51 }

默慈金数代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstring>
 5
 6 using namespace std;
 7
 8 const long long mod=1000000007;
 9 long long n;
10 long long ans[1100000];
11 long long power(long long a,long long n,long long m)
12 {
13     long long ans=1,tmp=a;
14     while(n)
15     {
16         if(n&1)
17             ans=ans*tmp%m;
18         tmp=tmp*tmp%m;
19         n=n>>1;
20     }
21     return ans;
22 }
23
24 int main()
25 {
26     ans[1]=1;
27     ans[2]=2;
28     for(long long i=2;i<=1000000;i++)
29         ans[i+1]=((2*i+3)%mod*ans[i]%mod+3*i*ans[i-1]%mod)%mod*power(i+3,mod-2,mod)%mod;
30     int T;
31     scanf("%d",&T);
32     while(T--)
33     {
34         scanf("%lld",&n);
35         cout<<ans[n]<<endl;
36     }
37     return 0;
38 }

  

时间: 2024-08-06 03:45:33

hdu5673 Robot 卡特兰数 / 默慈金数的相关文章

51NOD 1556 计算 (默慈金数)

传送门 有一个1*n的矩阵 固定第一个数为1 其他填正整数 且相邻数的差不能超过1 求方案数%1e9+7的结果 Input 一个数n 表示1*n的矩阵(n<=10^6) Output 一个数 表示方案数%1e9+7的结果 Input示例 3 Output示例 5 解题思路: 这是一个默慈金数的题目,那么什么叫默慈金数呢. 默慈金数是在数学中,一个给定的数n的默慈金数是"在一个圆上的n个点间,画出彼此不相交的弦的全部方法的总数".--摘自百度百科 默慈金数的实例表示:像例如在一个&

HDU 3723 Delta Wave(默慈金数)

传送门 Delta Wave Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1160    Accepted Submission(s): 370 Problem Description A delta wave is a high amplitude brain wave in humans with a frequency of 1

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

hdu-5673 Robot(默次金数)

题目链接: Robot Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) 问题描述 有一个机器人位于坐标原点上.每秒钟机器人都可以向右移到一个单位距离,或者在原地不动.如果机器人的当前位置在原点右侧,它同样可以 向左移动单位距离.一系列的移动(左移,右移,原地不动)定义为一个路径.问有多少种不同的路径,使得nn秒后机器人仍然位于坐标原点? 答案可能很大,只需输出答案对1,000,00

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 rig

Python 素数判断;以及默尼森数

1. 素数/质数 只能被2或者本身整除的正整数. 2. 默尼森数 P是素数且M也是素数,并且满足等式M=2^P-1,则称M为默尼森数. 编程小要求: 输出前5个默尼森数 1)最外层循环找素数 中间层循环对已有素数表找默尼森数 内层循环对某个素数检查M=2^P-1 1 # -*- coding: cp936 -*- 2 from math import sqrt 3 4 # 素数初始化 5 p=[] 6 # 默尼森数表初始化 7 mns=[] 8 9 def is_sushu(x): 10 if

python 脚本(获取指定文件夹、指定文件格式、的代码行数、注释行数)

1.代码的运行结果: 获取 指定文件夹下.指定文件格式 文件的: 总代码行数.总注释行数(需指定注释格式).总空行数: 1 #coding: utf-8 2 import os, re 3 4 # 代码所在目录 5 FILE_PATH = './' 6 7 def analyze_code(codefilesource): 8 ''' 9 打开一个py文件,统计其中的代码行数,包括空行和注释 10 返回含该文件总行数,注释行数,空行数的列表 11 ''' 12 total_line = 0 13

Fibonacci数列是这样定义的: F[0] = 0 F[1] = 1 for each i ≥ 2: F[i] = F[i-1] + F[i-2] 因此,Fibonacci数列就形如:0, 1, 1, 2, 3, 5, 8, 13, ...,在Fibonacci数列中的数我们称为Fibonacci数。给你一个N,你想让其变为一个Fibonacci数,每一步你可以把当前数字X变为X-1或者X+1

Fibonacci数列是这样定义的:F[0] = 0F[1] = 1for each i ≥ 2: F[i] = F[i-1] + F[i-2]因此,Fibonacci数列就形如:0, 1, 1, 2, 3, 5, 8, 13, ...,在Fibonacci数列中的数我们称为Fibonacci数.给你一个N,你想让其变为一个Fibonacci数,每一步你可以把当前数字X变为X-1或者X+1,现在给你一个数N求最少需要多少步可以变为Fibonacci数. 输入描述: 输入为一个正整数N(1 ≤ N

C++统计代码注释行数 &amp; 有效代码行数 &amp; 代码注释公共行 &amp; 函数个数

问题来源,在14年的暑假的一次小项目当中遇到了一个这样的问题,要求统计C++代码的注释行数,有效代码行数,代码注释公共行数,以及函数个数. 下面稍微解释一下问题, 1)注释行数:指有注释的行,包括有代码和注释的公共行(如:3,4,15,22...) 2)有效代码行:指有代码的行,包括有代码和注释的公共行(如:1,4,11,15,25....) 3)代码注释公共行:指又有代码又有注释的行(如:4,15...) 4)函数个数:这个不用说明了吧. 以下为注释情况展示代码: 1 #include <st