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;
}


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