ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Codeforces-1095E-Almost-Regular-Bracket-Sequence

2019-12-16 17:50:55  阅读:282  来源: 互联网

标签:leq Almost sum Sequence Codeforces int maxn 括号 翻转


题意

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

分析

括号序列显然采取前缀和思想,将\('('\)记做\(1\),将\(')'\)记做\(-1\),记为\(sum[]\)数组,并统计\('('\)的前缀和,即为\(suml[]\)数组,统计\(')'\)的前缀和,即为\(sumr[]\)数组。

可以发现,对于某一个序列,只能翻转\('('\)或\(')'\)一种类型,分类进行分析:

\((1)\)\('('\)比\(')'\)多\(2\)个,则翻转\('('\)可以使得\(sum[n]\)变为\(0\)。考虑翻转第\(i\)位的\('('\)会产生的影响。对于\(i\leq j\leq n\)来说,所有的\(sum[j]\)都减去\(2\),所以要保证所有的\(sum[]\)都大于0,即找到\(i\),有

  • \(1\leq k <i\),\(sum[k]>=0\)
  • \(i < j \leq n\),\(sum[j]>=2\)
  • \(sum[i]=1\)

答案即为\(i\)~\(n\)中\('('\)数量。

\((2)\)\('('\)比\(')'\)少\(2\)个,可以通过翻转字符串并将所有的\('('\)和\(')'\)翻转获得第\((1)\)种情况。也可以通过考虑翻转第\(i\)位的\(')'\)会产生的影响,对于\(i\leq j\leq n\)来说,所有的\(sum[j]\)都加上\(2\),所以要保证所有的\(sum[]\)都大于0,即找到\(i\),有

  • \(1\leq k <i\),\(sum[k]>=0\)
  • \(i < j \leq n\),\(sum[j]>=-2\)
  • \(sum[i]=-1\)

答案即为\(1\)~\(i\)中的\(')'\)数量。

\((3)\)其他情况输出\(0\)即可,存在已经为括号序列的字符串,也存在不可能满足条件的字符串。

#pragma GCC optimize(3, "Ofast", "inline")

#include <bits/stdc++.h>

#define start ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define ll long long
#define LL long long
#define int ll
using namespace std;
const int maxn = (ll) 1e6 + 5;
const int mod = 1000000007;
const int inf = 0x3f3f3f3f;
int sum[maxn];
int suml[maxn];
int sumr[maxn];
char s[maxn];

signed main() {
    start;
    int n;
    cin >> n;
    cin >> (s + 1);
    for (int i = 1; i <= n; ++i) {
        suml[i] = suml[i - 1];
        sumr[i] = sumr[i - 1];
        if (s[i] == '(')
            sum[i] = sum[i - 1] + 1, ++suml[i];
        else
            sum[i] = sum[i - 1] - 1, ++sumr[i];
    }
    if (sum[n] == 2) {
        for (int i = 1; i <= n; ++i)
            if (sum[i] < 0) {
                cout << 0;
                return 0;
            }
        int l = n;
        for (; l > 0; --l)
            if (sum[l] == 1)
                break;
        cout << suml[n] - suml[l];
    } else if (sum[n] == -2) {
        for (int i = 1; i <= n; ++i)
            if (sum[i] < -2) {
                cout << 0;
                return 0;
            }
        int l = 1;
        for (; l <= n; ++l)
            if (sum[l] == -1)
                break;
        cout << sumr[l];
    } else
        cout << 0;
    return 0;
}

标签:leq,Almost,sum,Sequence,Codeforces,int,maxn,括号,翻转
来源: https://www.cnblogs.com/F-Mu/p/12050362.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有