BC # 32 1003

题意:定义了括号的合法排列方式,给出一个排列的前一段,问能组成多少种合法的排列。

这道题和鹏神研究卡特兰数的推导和在这题中的结论式的推导:

首先就是如何理解从题意演变到卡特兰数:

排列的总长度为 n ,左右括号各为 m = n / 2 个。当给定的排列方式完全合法的时候,剩下需要排列的左右括号的数量就已经确定了,而在排列的过程中,左括号要始终大于等于右括号的数量。设现在有 a 个左括号, b 个右括号,那么这个就可以当做从( a , b )点到 ( m , m )点且不越过直线 y = x 的种类数。将图像下移,则可认为是从( 0 , 0 )点到 ( p , q )点且不越过直线 y = x 的种类数。

求种类数则是用总的种类数减去非法种类数。总的种类数可用组合数学 C(p+q,p),而非法种类数则是通过图形移动,将图形向下移动一个单位,原本要求越过 y = x ,移动后只要从( 0 , - 1 )点到( p , q - 1 )点且经过 y = x 的路径都是非法的。而计算这个种类数则可以用( 0 , - 1 )与( - 1 , 0 )关于 y = x 对称得,只要从计算从( - 1 , 0 )点到( p , q - 1 )的种类数即可,因为这两点分别在 y = x 的上下,所以路径一定经过 y = x ,种类数为 C ( p + q ,p - 1 );

相减得到 (( q - p + 1 ) / ( q + 1 )) * C(p+q,p);

但事实上,直接这样计算是会超时的,因此可以将这个式子继续化成:

(( p + q )!*( q - p + 1 ))/((q + 1)!* p!)

在这个式子中大量用到阶乘就是为了可以直接在开始时预处理出阶乘来缩短时间。

而除法则用到了求逆元。

  1. #include<stdio.h>
  2. #include<string.h>
  3. #define ll long long
  4. const ll mod=;
  5. char s[];
  6. ll A[];
  7.  
  8. void fun(){
  9. A[]=A[]=;
  10. for(int i=;i<=;i++){
  11. A[i]=(A[i-]*i)%mod;
  12. }
  13. }
  14. /*
  15. ll C(ll a,ll b){
  16. ll i,ans=1;
  17. for(i=1;i<=b;i++){
  18. ans*=a-i+1;
  19. ans/=i;
  20. }
  21. return ans;
  22. }
  23. */
  24. ll QuickPow(ll a,ll n){
  25. ll tmp=a,ans=;
  26. tmp %= mod;
  27. while(n){
  28. if(n&) ans=ans*tmp%mod;
  29. tmp=tmp*tmp%mod;
  30. n>>=;
  31. }
  32. return ans;
  33. }
  34.  
  35. int main(){
  36. int n;
  37. fun();
  38. while(scanf("%d%s",&n,s)!=EOF){
  39. if(n%)printf("0\n");
  40. else{
  41. int p=,q=,i,l=strlen(s);
  42. for(i=;i<l;i++){
  43. if(s[i]=='(')p++;
  44. else q++;
  45. if(p<q){
  46. printf("0\n");
  47. break;
  48. }
  49. }
  50. if(p<q) continue;
  51. {
  52. p=n/-p;
  53. q=n/-q;
  54. if(p<||q<){
  55. printf("0\n");
  56. continue;
  57. }
  58. ll r1=QuickPow(A[p],mod-),r2=QuickPow(A[q+],mod-);
  59. ll ans=A[p+q];
  60. // printf("%lld %lld %lld\n",ans,r1,r2);
  61. ans=(ans*((q-p+)%mod))%mod;
  62. ans=(ans*r1)%mod;
  63. ans=(ans*r2)%mod;
  64. printf("%I64d\n",ans);
  65.  
  66. }
  67. }
  68. }
  69. return ;
  70. }

hdu 5184 类卡特兰数+逆元的更多相关文章

  1. hdu 5673 Robot 卡特兰数+逆元

    Robot Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Problem D ...

  2. hdu 4828 Grids 卡特兰数+逆元

    Grids Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others) Problem D ...

  3. hdu 5184(数学-卡特兰数)

    Brackets Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Su ...

  4. HDU 4828 (卡特兰数+逆元)

    HDU 4828 Grids 思路:能够转化为卡特兰数,先把前n个人标为0,后n个人标为1.然后去全排列,全排列的数列,假设每一个1的前面相应的0大于等于1,那么就是满足的序列.假设把0看成入栈,1看 ...

  5. HDOJ 5184 Brackets 卡特兰数扩展

    既求从点(0,0)仅仅能向上或者向右而且不穿越y=x到达点(a,b)有多少总走法... 有公式: C(a+b,min(a,b))-C(a+b,min(a,b)-1)  /// 折纸法证明卡特兰数: h ...

  6. hdu_4828_Grids(卡特兰数+逆元)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=4828 题意:中文,不解释 题解:实际就是一个卡特兰递推: Catalan(n+1)= Catalan( ...

  7. 【HDU 5184】 Brackets (卡特兰数)

    Brackets Problem Description We give the following inductive definition of a “regular brackets” sequ ...

  8. HDU 4828 Grids(卡特兰数+乘法逆元)

    首先我按着我的理解说一下它为什么是卡特兰数,首先卡特兰数有一个很典型的应用就是求1~N个自然数出栈情况的种类数.而这里正好就对应了这种情况.我们要满足题目中给的条件,数字应该是从小到大放置的,1肯定在 ...

  9. HDU 4828 (卡特兰数+逆)

    HDU 4828 Grids 思路:能够转化为卡特兰数,先把前n个人标为0.后n个人标为1.然后去全排列,全排列的数列.假设每一个1的前面相应的0大于等于1,那么就是满足的序列,假设把0看成入栈,1看 ...

随机推荐

  1. Xshell Xftp 免费版 (xshell6 评估期已过 解决办法)

    xshell6 评估期已过,因为下载的版本是evaluation版本,是有期限的. 大家可以修改为Home and school use 的版本,这样就不会出现这个提示了. 具体的操作步骤如下: 1. ...

  2. Jmeter JDBC的使用

    1.当我们在对接口进行断言或进行多个接口串联时,常常会需要从DB查询数据来做辅助,连接JDBC需要有支持DB的jar包:官网下载地址:https://dev.mysql.com/downloads/c ...

  3. python-day9-集合数据类型

    pythons=['alex','egon','yuanhao','wupeiqi','gangdan','biubiu']linuxs=['wupeiqi','oldboy','gangdan'] ...

  4. javascript数据结构——栈

    栈是一种高效的数据结构,数据只能在栈顶添加或删除,所以这样操作很快,也很容易实现.栈的使用遍布程序语言实现的方方面面,从表达式求值到处理函数调用.接下来,用JavaScript实现一个栈的数据结构. ...

  5. WEBSERVICE-AXIS2服务端代码

    下载axis2的插件 axis2-eclipse-codegen-plugin-1.7.1.zip axis2-eclipse-service-plugin-1.7.1.zip 解压后,将plugin ...

  6. (zz)设置单元格的宽度和高度

    (zz)设置单元格的宽度和高度 博客分类: POI生成Excel   在Excel中,单元格的宽度其实就是列的宽度,因为Excel假设这一列的单元格的宽度肯定一致.所以要设置单元格的宽度,我们就得从列 ...

  7. 推荐八款.Net优秀的开源CMS 内容管理系统

    1,老牌内容管理系统SiteServer CMS  推荐指数:5 SiteServer CMS 是.NET平台的CMS系统,也是一款拥有十年历史与广泛知名度的CMS系统,2017年5月初迈出了自成立以 ...

  8. @one to many 和 @many to one小例子

    一个机构  : 多个用户 OrgTable实体类 :User实体类 OrgTable.java(一) 注解@OnetoMany,mappedBy=“org”,就是由“多”的那端维护(下面User类定义 ...

  9. Java——IO类 字节流概述

    body, table{font-family: 微软雅黑} table{border-collapse: collapse; border: solid gray; border-width: 2p ...

  10. LeetCode OJ:Valid Number

    Validate if a given string is numeric. Some examples:"0" => true" 0.1 " => ...