(https://codeforces.com/contest/1556/problem/C)
给定一个数组,下标为奇数的表示左括号连续数目,反之则表示右括号连续数目,求有多少个区间满足的括号满足正则表达式
我们可以计算从l+1到r−1段上的最小支架平衡。最小括号平衡是我们必须放置在括号序列之前的最小开始括号数量,以使它是规则的,前提是我们可以在末尾放置任意数量的结束括号。让我们将这个数字表示为minBalance,并将- cl+1+cl+2 - cl+2+…的总和表示为balance。
下观察,如果我们解决开括号取自cl的数量,然后我们可以计算括号的数量,我们应该从cr。使用这些观察我们可以计算的答案l . . r使用以下公式:min (cl, cr−balance)−max(minBalance) + 1。
#include <bits/stdc++.h> using namespace std; #define lowbit(x) x & -x #define int long long const int N=1100; int a[N]; signed main(){ int n; cin>>n; for(int i=1;i<=n;i++){ cin>>a[i]; } int cnt=0; for(int i=1;i<=n;i+=2){ int sum=0;int l=0; for(int j=i+1;j<=n;j++){ if(j%2==0){ int ll=-l; ll=max(1ll,ll); ll=max(ll,1-sum); int r=min(a[i],a[j]-sum);//a[j]减去之前留下的左括号代表还剩的右括号和a[i]的左括号取小值; if(r>=ll) cnt+=r-ll+1;//减去最少要添加左括号的数目后 } if(j%2) sum+=a[j]; else sum-=a[j]; l=min(l,sum);//在最前面至少要添加多少有个左括号 } } cout<<cnt<<endl; }