又是一道前缀后缀题,去掉l,r之后,最大值是max(pre_max[l-1],max(0,ed_max[r+1])+pre[l-1]);
最小值一样。
注意做后缀的时候以0为基准,过了就重置了,因为取最大值,所以带来负影响的干脆不要。
下附代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int INF=0X3f3f3f3f; 4 int pre[200005],pre_max[200005],pre_min[200005],ed[200005],ed_max[200005],ed_min[200005]; 5 char s[200005]; 6 int n,m; 7 int main(){ 8 int T; 9 scanf("%d",&T); 10 while (T--){ 11 scanf("%d%d",&n,&m); 12 scanf("%s",s+1); 13 pre[0]=0; 14 pre_max[0]=0; 15 pre_min[0]=0; 16 ed_max[n+1]=0; 17 ed_min[n+1]=0; 18 for (int i=1; i<=n; i++){ 19 pre[i]=pre[i-1]; 20 if (s[i]=='-') pre[i]--; 21 else pre[i]++; 22 pre_max[i]=max(pre_max[i-1],pre[i]); 23 pre_min[i]=min(pre_min[i-1],pre[i]); 24 } 25 for (int i=n; i>=1; i--){ 26 ed_max[i]=max(0,ed_max[i+1]+(s[i]=='+'?1:-1)); 27 ed_min[i]=min(0,ed_min[i+1]+(s[i]=='+'?1:-1)); 28 } 29 while (m--){ 30 int l,r; 31 scanf("%d%d",&l,&r); 32 int maxn=max(pre_max[l-1],pre[l-1]+max(ed_max[r+1],0)); 33 int minn=min(pre_min[l-1],pre[l-1]+min(ed_min[r+1],0)); 34 printf("%d ",maxn-minn+1); 35 } 36 } 37 }