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 }
原文地址:https://www.cnblogs.com/Opaser/p/4337646.html