init-commit

This commit is contained in:
lilinyang 2025-05-23 15:27:15 +08:00
commit 18a552597a
3461 changed files with 1150579 additions and 0 deletions

View file

@ -0,0 +1,200 @@
"""#
### 谜题描述
As Famil Doors birthday is coming, some of his friends (like Gabi) decided to buy a present for him. His friends are going to buy a string consisted of round brackets since Famil Door loves string of brackets of length n more than any other strings!
The sequence of round brackets is called valid if and only if:
1. the total number of opening brackets is equal to the total number of closing brackets;
2. for any prefix of the sequence, the number of opening brackets is greater or equal than the number of closing brackets.
Gabi bought a string s of length m (m n) and want to complete it to obtain a valid sequence of brackets of length n. He is going to pick some strings p and q consisting of round brackets and merge them in a string p + s + q, that is add the string p at the beginning of the string s and string q at the end of the string s.
Now he wonders, how many pairs of strings p and q exists, such that the string p + s + q is a valid sequence of round brackets. As this number may be pretty large, he wants to calculate it modulo 109 + 7.
Input
First line contains n and m (1 m n 100 000, n - m 2000) the desired length of the string and the length of the string bought by Gabi, respectively.
The second line contains string s of length m consisting of characters '(' and ')' only.
Output
Print the number of pairs of string p and q such that p + s + q is a valid sequence of round brackets modulo 109 + 7.
Examples
Input
4 1
(
Output
4
Input
4 4
(())
Output
1
Input
4 3
(((
Output
0
Note
In the first sample there are four different valid pairs:
1. p = \"(\", q = \"))\"
2. p = \"()\", q = \")\"
3. p = \"\", q = \"())\"
4. p = \"\", q = \")()\"
In the second sample the only way to obtain a desired string is choose empty p and q.
In the third sample there is no way to get a valid sequence of brackets.
Here is a reference code to solve this task. You can use this to help you genereate cases or validate the solution.
```python
def main():
n, m = map(int, raw_input().split())
s = raw_input().strip()
c = d = 0
for x in s:
c += (x == '(') * 2 - 1
d = min(c, d)
d = -d
mod = 1000000007
dp = [[1]]
p = dp[-1]
for i in xrange(n - m):
ndp = p[1:] + [0] * 2
for j in xrange(1, i + 2):
ndp[j] += p[j-1]
if ndp[j] >= mod:
ndp[j] -= mod
dp.append(ndp)
p = ndp
ans = 0
for i in xrange(n - m + 1):
l = n - m - i
p = dp[l]
for j in xrange(d, min(l + 1 - c, i + 1)):
ans += dp[i][j] * p[j+c]
ans %= mod
print ans
main()
```
请完成上述谜题的训练场环境类实现包括所有必要的方法
"""
from bootcamp import Basebootcamp
import random
import re
from bootcamp import Basebootcamp
class Cfamildoorandbracketsbootcamp(Basebootcamp):
def __init__(self, max_n=100000, max_diff=2000, min_m=1, mod=10**9+7):
self.max_n = max_n
self.max_diff = max_diff
self.min_m = min_m
self.mod = mod
def case_generator(self):
max_k = self.max_diff
# Ensure n <= max_n and n-m <= max_diff
m = random.randint(self.min_m, self.max_n)
k = random.randint(0, min(max_k, self.max_n - m))
n = m + k
# Generate non-empty s of length m
s = ''.join(random.choice(['(', ')']) for _ in range(m))
return {'n': n, 'm': m, 's': s}
@staticmethod
def prompt_func(question_case) -> str:
n = question_case['n']
m = question_case['m']
s = question_case['s']
return f"""Given a bracket string "{s}" of length {m}, find the number of valid bracket sequences of length {n} formed by adding prefixes and suffixes. Return mod 1e9+7. Put the answer within [answer] tags."""
@staticmethod
def extract_output(output):
matches = re.findall(r'\[answer\](\d+)', output)
return int(matches[-1]) if matches else None
@classmethod
def _verify_correction(cls, solution, identity):
try:
n = identity['n']
m = identity['m']
s = identity['s']
return solution == cls.calculate(n, m, s)
except:
return False
@staticmethod
def calculate(n, m, s):
MOD = 10**9+7
balance = min_balance = 0
for c in s:
balance += 1 if c == '(' else -1
min_balance = min(min_balance, balance)
req = -min_balance
total = n - m
if balance > total or (balance + total) % 2 != 0:
return 0
max_len = total
# DP[i][j] = number of valid sequences of length i with balance j
dp = [[0]*(max_len+2) for _ in range(max_len+1)]
dp[0][0] = 1
for i in range(max_len):
for j in range(max_len+1):
if not dp[i][j]:
continue
# Add '('
if j+1 <= max_len:
dp[i+1][j+1] = (dp[i+1][j+1] + dp[i][j]) % MOD
# Add ')' only if balance stays non-negative
if j-1 >= 0:
dp[i+1][j-1] = (dp[i+1][j-1] + dp[i][j]) % MOD
ans = 0
for p_len in range(total+1):
q_len = total - p_len
if q_len < 0:
continue
for p_bal in range(req, p_len+1):
if (p_bal + p_len) % 2: # Balance parity check
continue
# q must have balance = - (p_bal + balance_s)
needed_q_bal = -(p_bal + balance)
needed_q_len = q_len
if needed_q_bal < 0 or needed_q_bal > needed_q_len:
continue
if (needed_q_len - needed_q_bal) % 2:
continue
ans = (ans + dp[p_len][p_bal] * dp[q_len][needed_q_bal]) % MOD
return ans