zoukankan      html  css  js  c++  java
  • hdu5184 数论证明

    这题说的给了一个整数n 和一串的括号, 那么要我们计算 最后有n/2对括号的 方案数有多少。

    我们可以先预先判断一些不可能组成正确括号对的情况,

    然后我们可以将这个问题转化到二维平面上, 令 m = n/2  ,L 为左括号的个数 R为右括号的个数  可以知道还有 m - L 个左括号没用, 有m-R个右括号没用,令他们分别我p=m-R,q=m-L, 然后机的就是 (0,0)点到 (p,q)点 不跨过x=y这条线的方案数,那么我们可以这样做,将 (0,0) 向下移动 1 个单位,(0,-1)-》》》》》(p,q-1) , 假设如果非法那么必须会经过(d,d)这个点,我们知道从(0,-1)到(d,d)和(-1,0)到(d,d)的方案数是一样的,那么我们就知道了从(0,1) 出发的非法的方案数为 (-1,0) 到(p.q-1) 的方案数,那么最终的答案就是 C(p+q,q)-C(p+q,q-1);

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <algorithm>
     4 #include <string.h>
     5 #include <vector>
     6 using namespace std;
     7 const int maxn = 1000000+10;
     8 typedef long long LL;
     9 const LL mod = 1000000007;
    10 LL dp[maxn];
    11 LL mdp[maxn];
    12 LL vdp[maxn];
    13 char str[maxn];
    14 void gcd(LL a, LL b, LL &d, LL &x, LL &y){
    15       if(!b) {d=a; x= 1; y =0;}
    16       else{gcd(b,a%b,d,y,x); y -= x*(a/b);}
    17 }
    18 LL inv(LL a, LL n){
    19     LL d,x,y;
    20     gcd(a,n,d,x,y);
    21     return d==1 ? (x+n)%n:-1;
    22 }
    23 int main()
    24 {
    25     dp[0]=1;
    26     for(LL i=1; i<=1000000; ++i){
    27        dp[i]=(dp[i-1]* i)%mod;
    28     }
    29     int n;
    30     while(scanf("%d",&n)==1){
    31         scanf("%s",str);
    32 
    33          if(n%2){
    34               printf("0
    "); continue;
    35          }
    36          LL m = n/2;
    37          int len =strlen(str);
    38          LL L=0,R=0;
    39          for(int i=0; i<len; ++i){
    40              if(str[i]=='(') L++;
    41              else if(str[i]==')')R++;
    42              if(L<R){
    43                  L=-1; break;
    44              }
    45          }
    46          if(L==-1||L>m){
    47               printf("0
    ");continue;
    48          }
    49          if(L==R&&L+R==n){
    50              printf("1
    ");continue;
    51          }
    52           L=m - L;
    53           R=m - R;
    54           LL d0 = L;
    55           L=R; R=d0;
    56           LL d1 = inv(L+1,mod);
    57 
    58           LL d2 = inv(dp[L],mod);
    59           LL d3 = inv(dp[R],mod);
    60 
    61           LL ans =( ( ( ( ( ( ( ( L-R+1 )*d1 )%mod) * d2 )%mod) * d3)%mod) * dp[L+R])%mod;
    62           printf("%I64d
    ",ans);
    63     }
    64 
    65     return 0;
    66 }
  • 相关阅读:
    一些性能查询的SQL 备忘
    Oracle Stream配置详细步骤
    Oracle 一次生产分库,升级,迁移
    Oracle数据文件和临时文件的管理
    db_recovery_file_dest_size 修改大一点及删除归档日志 |转|
    android启动优化
    C++ primer 中文第三版 阅读笔记 第八章
    XMPP通讯开发-好友获取界面设计
    用SHELL与列表处理了件尴尬事
    各种快递查询--Api接口
  • 原文地址:https://www.cnblogs.com/Opaser/p/4337646.html
Copyright © 2011-2022 走看看