zoukankan      html  css  js  c++  java
  • [CF1095E] Almost Regular Bracket Sequence

    Description

    给定一个长度为 $ n $ 的小括号序列,求有多少个位置满足将这个位置的括号方向反过来后使得新序列是一个合法的括号序列。即在任意一个位置前缀左括号的个数不少于前缀右括号的个数,同时整个序列左右括号个数相同 $ 1 leq n leq 10^6 $

    Solution

    将左括号记为 (1),右括号记为 (-1),这个数字序列记为 (a[]),它的前缀和记为 (s[]),同时记录每一个后缀 (a[i..n]) 的最小前缀 (f[i])

    计算 (f[]) 时,只需要倒序递推即可(类似最大子段和的处理)

    如果一个位置 (i),满足所有 (i) 之前的前缀都合法,且 (s[n]-2a[i]=0),并且 (s[i-1]-a[i]+f[i+1] ge 0),则这个位置是满足条件的

    #include <bits/stdc++.h>
    using namespace std;
    
    
    #define int long long
    const int N = 1000005;
    
    int n,a[N],s[N],f[N];
    char c[N];
    
    signed main() {
        ios::sync_with_stdio(false);
        cin>>n>>c+1;
        for(int i=1;i<=n;i++) a[i]=c[i]=='('?1:-1;
        for(int i=1;i<=n;i++) s[i]=s[i-1]+a[i];
        for(int i=n;i>=1;--i) f[i]=min(0ll,f[i+1]+a[i]);
        int ans=0;
        int lim=0,cnt=0;
        for(int i=1;i<=n;i++) {
            cnt+=a[i];
            ++lim;
            if(cnt<0) break;
        }
        for(int i=1;i<=lim;i++) if(s[n]-2*a[i]==0 && s[i-1]-a[i]+f[i+1]>=0) ++ans;
        cout<<ans;
    }
    
  • 相关阅读:
    入门学习嵌入式260期手把手配套视频7个项目实战送书
    使用from 的setTimeOut方法实现定时关闭Form
    C#面试题
    《JS语法字典》网友总结
    简单SQL语句小结
    面试前的简历
    Hello World的17种写法(C#)(转贴)
    张芸京 偏爱
    关于我对.setTmp()的理解及应用
    VS 2005使用技巧
  • 原文地址:https://www.cnblogs.com/mollnn/p/12830724.html
Copyright © 2011-2022 走看看