CF_5C_LongestRegularBracketSequence

C. Longest Regular Bracket Sequence
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

This is yet another problem dealing with regular bracket sequences.

We should remind you that a bracket sequence is called regular, if by inserting «+» and «1» into it we can get a correct mathematical expression. For example, sequences «(())()», «()» and «(()(()))» are regular, while «)(», «(()» and «(()))(» are not.

You are given a string of «(» and «)» characters. You are to find its longest substring that is a regular bracket sequence. You are to find the number of such substrings as well.

Input

The first line of the input file contains a non-empty string, consisting of «(» and «)» characters. Its length does not exceed 106.

Output

Print the length of the longest substring that is a regular bracket sequence, and the number of such substrings. If there are no such substrings, write the only line containing "0 1".

Examples
input
)((())))(()())
output
6 2
input
))(
output
0 1

题目意思求给出的括号串中最长的合法括号序列


这题目最开始想的用1 -1前缀和解决 但是发现很多情况并不能处理


这里可以这样想 首先)肯定是匹配的最近的没有匹配的(

不然一定出现没有匹配的或者交替匹配的

于是可以把(入栈 遇到)则出栈一个

而 目前两个()之间的括号序列一定是匹配的

于是只需要把所有的(的位置入栈 出栈时计算下即可知道当前括号序列的长度

但是 这里注意到一点 一个合法的括号序列并不一定是(…… 序列 ……)这样的形式

也可能是(……)(……)这样的形式

于是 用一个数组管理到目前位置的合法序列长度 于是每次得到匹配的括号更新这个值即可

有点dp思想


#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stack>
using namespace std;

const int M=1e6+5;
char s[M];
int n[M];//保存到当前位置最长的合法序列长度

stack<int> st;

int main()
{
    scanf("%s",s+1);
    int l=strlen(s+1);
    int ml=0,mn=1;
    //最大子串长度,子串个数
//    int su=0;   //前缀和
    for(int i=1;i<=l;i++)
    {
        if(st.empty()&&s[i]==')')
            continue;
        if(s[i]==')')
        {
            n[i]=i-st.top()+1+n[st.top()-1];
            st.pop();
            if(n[i]==ml)
                mn++;
            if(n[i]>ml)
            {
                ml=n[i];
                mn=1;
            }
        }
        else
            st.push(i);
        //cout<<"i "<<i<<" nl "<<n[i]<<endl;
    }
    printf("%d %d\n",ml,mn);
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章