cf1473d

又是一道前缀后缀题,去掉l,r之后,最大值是max(pre_max[l-1],max(0,ed_max[r+1])+pre[l-1]);

最小值一样。

注意做后缀的时候以0为基准,过了就重置了,因为取最大值,所以带来负影响的干脆不要。

下附代码:

 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\n",maxn-minn+1);
35         }
36     }
37 }
View Code

 

posted @ 2021-01-28 22:13  我是菜狗QAQ  阅读(57)  评论(0编辑  收藏  举报