1478 括号序列的最长合法子段

1478 括号序列的最长合法子段

题目来源: CodeForces

基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题

这里有另一个关于处理合法的括号序列的问题。

如果插入“+”和“1”到一个括号序列,我们能得到一个正确的数学表达式,我们就认为这个括号序列是合法的。例如,序列"(())()", "()"和"(()(()))"是合法的,但是")(", "(()"和"(()))("是不合法的。

这里有一个只包含“(”和“)”的字符串,你需要去找到最长的合法括号子段,同时你要找到拥有最长长度的子段串的个数。

Input

第一行是一个只包含“(”和“)”的非空的字符串。它的长度不超过 1000000。

Output

输出合格的括号序列的最长子串的长度和最长子串的个数。如果没有这样的子串,只需要输出一行“0  1”。

Input示例

)((())))(()())

Output示例

6 2

//括号匹配,将 ( 做 1 , ) 为 -1 ,就可以得到一串数字,求出前缀和,那么,前缀和相同,并且,又端点的值是区间中最小的,即为合法序列,用单调栈维护一个上升前缀和即可。

 1 # include <bits/stdc++.h>
 2 using namespace std;
 3 # define LL long long
 4 # define INF 0x3f3f3f3f
 5 # define MX 100005
 6 /**************************/
 7 # define BUF_SIZE 1000005
 8 # define OUT_SIZE 1000005
 9 bool IOerror=0;
10
11 inline char nc(){
12     static char buf[BUF_SIZE],*p1=buf+BUF_SIZE,*pend=buf+BUF_SIZE;
13     if (p1==pend){
14         p1=buf; pend=buf+fread(buf,1,BUF_SIZE,stdin);
15         if (pend==p1){IOerror=1;return -1;}
16         //{printf("IO error!\n");system("pause");for (;;);exit(0);}
17     }
18     return *p1++;
19 }
20 inline bool blank(char ch){return ch==‘ ‘||ch==‘\n‘||ch==‘\r‘||ch==‘\t‘;}
21 inline void read(int &x){
22     bool sign=0; char ch=nc(); x=0;
23     for (;blank(ch);ch=nc());
24     if (IOerror)return;
25     if (ch==‘-‘)sign=1,ch=nc();
26     for (;ch>=‘0‘&&ch<=‘9‘;ch=nc())x=x*10+ch-‘0‘;
27     if (sign)x=-x;
28 }
29 inline void read(char *s){
30     char ch=nc();
31     for (;blank(ch);ch=nc());
32     if (IOerror)return;
33     for (;!blank(ch)&&!IOerror;ch=nc())*s++=ch;
34     *s=0;
35 }
36
37 const int N=1000005;
38 struct Node{
39     int dex;
40     int num;
41 };
42 char str[N];
43 int sum[N];
44 int ans[N];
45
46 int main ()
47 {
48     read(str+1);
49     int len = strlen(str+1);
50     for (int i=1;i<=len;++i)
51     {
52         sum[i] = sum[i-1] + (str[i]==‘(‘?1:-1);
53     }
54     stack<Node> st;
55     st.push((Node){0,0});
56     ans[0]=1;
57     for (int i=1;i<=len;++i)
58     {
59         while (!st.empty()&&sum[i]<st.top().num) st.pop();
60         if (!st.empty()&&sum[i]==st.top().num)
61         {
62             Node tp=st.top(); st.pop();
63             while (!st.empty()&&sum[i]==st.top().num)
64             {
65                 tp = st.top(); st.pop();
66             }
67             int ch = i-tp.dex;
68             ans[ch]++;
69             st.push(tp);
70         }
71         else st.push((Node){i,sum[i]});
72     }
73     int mdex=0;
74     for (int i=1;i<=len;++i)
75         if (ans[i]) mdex=i;
76     printf("%d %d\n",mdex,ans[mdex]);
77     return 0;
78 }

时间: 2024-08-25 16:59:31

1478 括号序列的最长合法子段的相关文章

【51NOD 1478】括号序列的最长合法子段

很恶心啊,一道水题改了半天,主要是各种细节没有注意到,包括左括号剩余时有可能会出错的情况,需要从后往前扫 贡献一组测试数据: ((()))())(())(( 答案:8 1 #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N = 1E6 + 3; char s[N]; int main() { scanf("%s", s); in

LongestValidParentheses, 求最长合法括号子串长度-----同类问题ValidParentheses,GenerateParentheses

问题描述:求括号字符串中最长合法子串长度.例如:()((),返回2,而不是4. 算法分析:还是利用栈,和判断合法括号对是一样的. 1 public static int longestValidParentheses(String s) { 2 Stack<int[]> stack = new Stack<int[]>(); 3 int result = 0; 4 5 for(int i=0; i<=s.length()-1; i++) 6 { 7 char c = s.ch

uoj #31. 【UR #2】猪猪侠再战括号序列 贪心

#31. [UR #2]猪猪侠再战括号序列 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://uoj.ac/problem/31 Description 大家好我是来自百度贴吧的_叫我猪猪侠,英文名叫_CallMeGGBond. 我不曾上过大学,但这不影响我对离散数学.复杂性分析等领域的兴趣:尤其是括号序列理论,一度令我沉浸其中,无法自拔.至于OI算法竞赛,我年轻时确有参加,虽仅获一枚铜牌,但我素性淡泊,毫不在意,毕竟那所谓FFT.仙人掌之类

UOJ#31 【UR #2】猪猪侠再战括号序列

传送门http://uoj.ac/problem/31 大家好我是来自百度贴吧的_叫我猪猪侠,英文名叫_CallMeGGBond. 我不曾上过大学,但这不影响我对离散数学.复杂性分析等领域的兴趣:尤其是括号序列理论,一度令我沉浸其中,无法自拔.至于OI算法竞赛,我年轻时确有参加,虽仅获一枚铜牌,但我素性淡泊,毫不在意,毕竟那所谓FFT.仙人掌之类,只是些雕虫小技罢了,登不上大雅之堂的:只有括号序列才会真正激发我的研究热情. 我曾天真地以为,凭借我的学识与才能,足可以在这世间安身立命:然而直到沦落

九度oj 题目1337:寻找最长合法括号序列

题目描述: 给你一个长度为N的,由’(‘和’)’组成的括号序列,你能找出这个序列中最长的合法括号子序列么?合法括号序列的含义便是,在这个序列中,所有的左括号都有唯一的右括号匹配:所有的右括号都有唯一的左括号匹配.例如:((()))()()便是一个长度为10的合法括号序列,而(()))( 则不是. 需要你求解的是,找出最长的合法括号子序列的长度,同时找出具有这样长度的序列个数. 输入: 测试数据包括多个,每个测试数据包含两行: 第一行为一个整数N,其中N不会超过10^6. 第二行为一个长度为N的字

九度oj 题目1342:寻找最长合法括号序列II

题目描述: 假如给你一个由’(‘和’)’组成的一个随机的括号序列,当然,这个括号序列肯定不能保证是左右括号匹配的,所以给你的任务便是去掉其中的一些括号,使得剩下的括号序列能够左右括号匹配且长度最长,即最长的合法括号序列. 输入: 测试数据包括多个,每个测试数据只有一行,即一个随机的括号序列,该括号序列的长度保证不超过106. 输出: 对于每个测试案例,输出一个整数,表示最后剩下的最长合法括号序列长度. 样例输入: (())() (() 样例输出: 6 2 这个题和1337求的是不一样的代码如下

[Jobdu] 题目1337:寻找最长合法括号序列

题目描述: 给你一个长度为N的,由’(‘和’)’组成的括号序列,你能找出这个序列中最长的合法括号子序列么?合法括号序列的含义便是,在这个序列中,所有的左括号都有唯一的右括号匹配:所有的右括号都有唯一的左括号匹配.例如:((()))()()便是一个长度为10的合法括号序列,而(()))( 则不是. 需要你求解的是,找出最长的合法括号子序列的长度,同时找出具有这样长度的序列个数. 输入: 测试数据包括多个,每个测试数据包含两行: 第一行为一个整数N,其中N不会超过10^6. 第二行为一个长度为N的字

网易2017秋招笔试题3:最长公共子括号序列长度

[问题来源]网传的2017网易秋招笔试题 [问题描述] [算法思路] 下面的解题思路摘自  http://www.cnblogs.com/Atanisi/p/7500186.html 刚看到题我就想到暴力解,深搜出所有合法的括号序列,再依次比较公共子序列的长度,返回最长的.但是深搜一般和路径有关,这道题仅仅需要最大公共子序列的长度.而我们发现最大公共子序列的长度就是 s.size() - 1(当且仅当修改距离为 1 时 LCS 最大), 那么我们就想到,可以变换 s 中一个括号的位置,枚举所有的

数据结构大师(求区间最长合法括号子序列)

数据结构大师 时间限制: 1 Sec 内存限制: 128 MB 题目描述 小$Z$是个数据结构高手,这天他得到了一个由左括号和右括号组成的字符串.随之而来的是 \(m\) 次询问,对于第 \(i\) 次询问,小Z需要回答出这个字符串的第$l_i$ 到$r_i$ 个字符组成的字串中最长的合法括号子序列的长度. 小$Z$认为一个由左右括号组成的序列$A$合法,当且仅当其满足至少一个以下条件. $A$为空. $A=(B)$其中$B$是一个合法的括号序列. \(A=BC\),其中$BC$都是合法的括号序