zoukankan      html  css  js  c++  java
  • Almost Regular Bracket Sequence CodeForces

    Almost Regular Bracket Sequence

    CodeForces - 1095E

    You are given a bracket sequence ss consisting of nn opening '(' and closing ')' brackets.

    A regular bracket sequence is a bracket sequence that can be transformed into a correct arithmetic expression by inserting characters '1' and '+' between the original characters of the sequence. For example, bracket sequences "()()", "(())" are regular (the resulting expressions are: "(1)+(1)", "((1+1)+1)"), and ")(" and "(" are not.

    You can change the type of some bracket sisi. It means that if si=si= ')' then you can change it to '(' and vice versa.

    Your task is to calculate the number of positions ii such that if you change the type of the ii-th bracket, then the resulting bracket sequence becomes regular.

    Input

    The first line of the input contains one integer nn (1≤n≤1061≤n≤106) — the length of the bracket sequence.

    The second line of the input contains the string ss consisting of nn opening '(' and closing ')' brackets.

    Output

    Print one integer — the number of positions ii such that if you change the type of the ii-th bracket, then the resulting bracket sequence becomes regular.

    Examples

    Input

    6
    (((())
    

    Output

    3
    

    Input

    6
    ()()()
    

    Output

    0
    

    Input

    1
    )
    

    Output

    0
    

    Input

    8
    )))(((((
    

    Output

    0
    

    翻译:

    赵老师实在是太强了,以至于他随便出的题就难倒了张老师
    他给了张老师一个括号序列S,其中只包含"("和")"
    他只允许张老师更改一个位置上的符号类型,如把"("变为")",从而使得整个括号序列是一个合法的括号序列
    请你帮张老师计算一下有几个位置,更改了这个位置的括号类型,整个括号序列将变成合法的括号序列

    思路:

    https://www.cnblogs.com/qieqiemin/p/11491557.html

    我这篇博客的题目是用线段树维护括号序列的最大合法匹配的子序列长度。(只有区间询问)

    如果不会建议前去学习。

    那么对于本题,

    我们可以增加一个单点更新的功能,然后对于1到n每一个字符,单点更新为相反的字符串。

    然后区间查询整个(即1~n)字符串的最大合法匹配的子序列长度是否为n,如果是就证明当前字符串是整体完美匹配的。答案+=1即可,然后将其再返过来更新,恢复成原始的字符串。再移步到下一个位置。统计最终答案即可。

    还有一种是分析性质和规律的做法,推荐这篇博客:https://blog.csdn.net/tianyizhicheng/article/details/86776263

    贴上我的ac代码

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <map>
    #include <set>
    #include <vector>
    #include <iomanip>
    #define ALL(x) (x).begin(), (x).end()
    #define sz(a) int(a.size())
    #define all(a) a.begin(), a.end()
    #define rep(i,x,n) for(int i=x;i<n;i++)
    #define repd(i,x,n) for(int i=x;i<=n;i++)
    #define pii pair<int,int>
    #define pll pair<long long ,long long>
    #define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
    #define MS0(X) memset((X), 0, sizeof((X)))
    #define MSC0(X) memset((X), '', sizeof((X)))
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    #define eps 1e-6
    #define gg(x) getInt(&x)
    #define chu(x) cout<<"["<<#x<<" "<<(x)<<"]"<<endl
    using namespace std;
    typedef long long ll;
    ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
    ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
    ll powmod(ll a, ll b, ll MOD) {ll ans = 1; while (b) {if (b % 2) { ans = ans * a % MOD; } a = a * a % MOD; b /= 2;} return ans;}
    inline void getInt(int *p);
    const int maxn = 1000010;
    const int inf = 0x3f3f3f3f;
    /*** TEMPLATE CODE * * STARTS HERE ***/
    struct node {
        int l, r;
        int num;
        int a;// (
        int b;// )
    } segmeng_tree[maxn << 2];
    char s[maxn];
    int n;
    int m;
    void pushup(int rt)
    {
        int x = min(segmeng_tree[rt << 1].a, segmeng_tree[rt << 1 | 1].b);
        segmeng_tree[rt].num = x + segmeng_tree[rt << 1].num + segmeng_tree[rt << 1 | 1].num;
        segmeng_tree[rt].a = segmeng_tree[rt << 1].a + segmeng_tree[rt << 1 | 1].a - x;
        segmeng_tree[rt].b = segmeng_tree[rt << 1].b + segmeng_tree[rt << 1 | 1].b - x;
    }
    void build(int rt, int l, int r)
    {
        segmeng_tree[rt].l = l;
        segmeng_tree[rt].r = r;
        if (l == r) {
            segmeng_tree[rt].a = s[l] == '(';
            segmeng_tree[rt].b = s[l] == ')';
            segmeng_tree[rt].num = 0;
        } else {
            int mid = (l + r) >> 1;
            build(rt << 1, l, mid);
            build(rt << 1 | 1, mid + 1, r);
            pushup(rt);
        }
    }
    
    node ask(int rt, int l, int r)
    {
        if (segmeng_tree[rt].l >= l && segmeng_tree[rt].r <= r) {
            return segmeng_tree[rt];
        }
        int mid = (segmeng_tree[rt].l + segmeng_tree[rt].r) >> 1;
        if (r <= mid) {
            return ask(rt << 1, l, r);
        } else if (l > mid) {
            return ask(rt << 1 | 1, l, r);
        } else {
            node res1 = ask(rt << 1, l, r);
            node res2 = ask(rt << 1 | 1, l, r);
            node res = res1;
            int x = min(res1.a, res2.b);
            res.num += x;
            res.b += res2.b;
            res.a += res2.a;
            res.num += res2.num;
            res.b -= x;
            res.a -= x;
            return res;
        }
    }
    void update(int rt, int x, int val)
    {
        if (segmeng_tree[rt].l == segmeng_tree[rt].r && segmeng_tree[rt].l == x)
        {
            if (val)
            {
                segmeng_tree[rt].a = 1;
                segmeng_tree[rt].b = 0;
            } else
            {
                segmeng_tree[rt].a = 0;
                segmeng_tree[rt].b = 1;
            }
        } else
        {
            int mid = (segmeng_tree[rt].r + segmeng_tree[rt].l) >> 1;
            if (x <= mid)
            {
                update(rt << 1, x, val);
            } else
            {
                update(rt << 1 | 1, x, val);
            }
            pushup(rt);
        }
    }
    int main()
    {
        //freopen("D:\code\text\input.txt","r",stdin);
        //freopen("D:\code\text\output.txt","w",stdout);
        scanf("%d",&n);
        scanf("%s", s + 1);
        // n = strlen(s + 1);
        build(1, 1, n);
        int ans = 0;
        repd(i, 1, n)
        {
            if (s[i] == '(')
            {
                update(1,i,0);
                int len=ask(1,1,n).num*2;
                if(len==n)
                {
                    ans++;
                }
                update(1,i,1);
            }else
            {
                update(1,i,1);
                int len=ask(1,1,n).num*2;
                if(len==n)
                {
                    ans++;
                }
                update(1,i,0);
            }
        }
        printf("%d
    ",ans );
        return 0;
    }
    
    inline void getInt(int *p)
    {
        char ch;
        do {
            ch = getchar();
        } while (ch == ' ' || ch == '
    ');
        if (ch == '-') {
            *p = -(getchar() - '0');
            while ((ch = getchar()) >= '0' && ch <= '9') {
                *p = *p * 10 - ch + '0';
            }
        } else {
            *p = ch - '0';
            while ((ch = getchar()) >= '0' && ch <= '9') {
                *p = *p * 10 + ch - '0';
            }
        }
    }
    
    
    本博客为本人原创,如需转载,请必须声明博客的源地址。 本人博客地址为:www.cnblogs.com/qieqiemin/ 希望所写的文章对您有帮助。
  • 相关阅读:
    【剑指offer】面试题40:数组中只出现一次的数字
    【剑指offer】面试题39扩展:平衡二叉树
    【剑指offer】面试题39:二叉树的深度
    【剑指offer】面试题38:数字在排序数组中出现的次数
    【剑指offer】面试题37:两个链表的第一个公共结点
    【剑指offer】面试题36:数组中的逆序对
    剑指Offer
    设计模式
    ACM
    算法设计与分析
  • 原文地址:https://www.cnblogs.com/qieqiemin/p/11504068.html
Copyright © 2011-2022 走看看