cf1263E(可修改判断括号是否为合法序列以及最大嵌套深度 线段树维护最大/小前缀和)

题目

题意

给你一段序列,其中L代表左移,R代表右移,小写字母代表在当前位置放置对应字母,),(代表在当前位置放置左右括号,当括号可以匹配时输出括号的最大层数,否则输出-1

题解

题解: sum==0&&mi[1]=0 为合法括号序列,mx[1]为括号嵌套最大深度。线段树维护最大前缀和 最小前缀和 详情见代码中update函数。
#include
using namespace std;
const int N=4e6+5;
char s[N];
int sum[N],mx[N],mi[N];
void update(int dex,int val,int l,int r,int pos){
    if(l==r){sum[pos]=mx[pos]=mi[pos]=val;return;}
    int mid=(l+r)>>1;
    if(dex<=mid) update(dex,val,l,mid,pos<<1);
    else update(dex,val,mid+1,r,pos<<1|1);
    sum[pos]=sum[pos<<1]+sum[pos<<1|1];
    mx[pos]=max(mx[pos<<1],sum[pos<<1]+mx[pos<<1|1]);
    mi[pos]=min(mi[pos<<1],sum[pos<<1]+mi[pos<<1|1]);
}
inline int get(char ch){return (ch=='('||ch==')')?((ch=='(')?1:-1):0;}
inline void calc(){printf("%d ",(sum[1]||mi[1]<0)?-1:mx[1]);}
int main(){
    int n,p=1;scanf("%d%s",&n,s+1);
    for(int i=1;i<=n;++i){
        if(s[i]=='L') {if(p>1) --p;calc();continue;}
        if(s[i]=='R') {++p,calc();continue;}
        update(p,get(s[i]),1,n,1);
        calc();
    }
}

你可能感兴趣的:(2020寒假,数据结构==线段树)