题目链接 Anton and School - 2
对于序列中的任意一个单括号对(),
左括号左边(不含本身)有a个左括号,右括号右边(不含本身有)b个右括号。
那么答案就为
但是这样枚举左右的()的话,最快情况复杂度为1e10,TLE。
所以对于每个左括号,把他右边的所有右括号一起来考虑。
对于每个左括号,令它左边(不含它本身)括号数位x,它右边右括号数位y。
那么当前答案为
![](https://images2015.cnblogs.com/blog/985728/201703/985728-20170323212908533-638892011.jpg)
复杂度O(Nlogmod),其中mod=1e9+7.
PS:代码中的这个y应该是上图的y-1.
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 #define rep(i, a, b) for(int i(a); i <= (b); ++i) 6 #define dec(i, a, b) for(int i(a); i >= (b); --i) 7 8 #define LL long long 9 10 const int N = 200000 + 10; 11 12 const LL mod = 1000000007; 13 14 LL c[N], f[N]; 15 char s[N]; 16 int n; 17 LL ans = 0; 18 LL fac[300010]; 19 20 inline LL Pow(LL a, LL b, LL Mod){ LL ret(1); for (; b; b >>= 1, (a *= a) %= Mod) if (b & 1) (ret *= a) %= Mod; return ret;} 21 22 inline LL C(LL n, LL m){ return m > n ? 0 : fac[n] * Pow(fac[m] * fac[n - m] % mod, mod - 2, mod) % mod; } 23 24 int main(){ 25 26 scanf("%s", s + 1); 27 n = strlen(s + 1); 28 29 fac[0] = 1; rep(i, 1, 200010) fac[i] = (fac[i - 1] * i) % mod; 30 31 memset(c, 0, sizeof c); 32 memset(f, 0, sizeof f); 33 rep(i, 1, n) if (s[i] == '(') c[i] = c[i - 1] + 1; else c[i] = c[i - 1]; 34 dec(i, n, 1) if (s[i] == ')') f[i] = f[i + 1] + 1; else f[i] = f[i + 1]; 35 36 rep(i, 1, n) if (s[i] == '('){ 37 LL x = c[i] - 1, y = f[i + 1] - 1; 38 39 40 (ans += C(x + y + 1, x + 1)) %= mod; 41 } 42 43 cout << ans << endl; 44 return 0; 45 46 }