括号匹配 RMQ/暴力
来源:互联网 发布:淘宝店铺介绍填写 编辑:程序博客网 时间:2024/05/18 09:57
Bobo has a balanced parenthesis sequence P=p1 p2…pn of length n and q questions.
The i-th question is whether P remains balanced after pai and pbi swapped. Note that questions are individual so that they have no affect on others.
Parenthesis sequence S is balanced if and only if:
1. S is empty;
2. or there exists balanced parenthesis sequence A,B such that S=AB;
3. or there exists balanced parenthesis sequence S’ such that S=(S’).
Input
The input contains at most 30 sets. For each set:
The first line contains two integers n,q (2≤n≤105,1≤q≤105).
The second line contains n characters p1 p2…pn.
The i-th of the last q lines contains 2 integers ai,bi (1≤ai,bi≤n,ai≠bi).
Output
For each question, output “Yes” if P remains balanced, or “No” otherwise.
Sample Input
4 2
(())
1 3
2 3
2 1
()
1 2
Sample Output
No
Yes
No
題意: 给出一个已经匹配的括号序列,任意的交换两个位置的括号,判断是否匹配,如果匹配输出 Yes 不匹配输出 No。
判断括号是否匹配的方法
int sum=0; for ( int i = 0; i < n; i++ ) { if ( s[i] == '(' ) sum++; // 遇到‘(’ sum+1 else sum--; // 遇到‘)’ sum-1 if ( sum < 0 ) break; // 如果 sum<0 则括号不匹配 }
分析参考:http://blog.csdn.net/bcwan_/article/details/52436229
分析:1.当左边的字符与右边的字符一样时,交换一定为括号平衡串 2.当左边的字符为')'时,交换一定为括号平衡串.因为一开始是平衡串, 如果左边的字符')'与右边的'('交换,那么此时交换的两个必能匹配为一对, 如果左边的字符')'与右边的')'交换,那么此时交换的两个字符相同,满足1. 3.当左边的字符为'('时,满不满足和右边位置左括号未匹配的个数有关. 建立前缀和数组a,表示当前位置左括号未匹配的个数, 当遇到左括号时前缀和+1,右括号时前缀和-1,那么由个例推出规律 ( ( ( ) ) ) 1 2 3 2 1 0 当a和b交换时,相对于改变前的前缀和,从a至(b-1) 前缀和都要减2(少了 一个‘+1’,多了一个‘-1’,所以比原来减少2),前缀和出现-1,括号就不匹配, 所以 当左边的'('与右边的交换能满足仍为括号平衡串的必须是在区间[a,b-1]内 的最小值>=2 所以问题转化为求区间[a,b-1]内的前缀和数组最小值是否满足>=2 可以用基于ST的RMQ算法,也可以用线段树求区间最小值
/* RMQ AC:204ms*/#include <iostream>#include <string>#include <cstring>#include <cstdio>#include <cmath>#include <cstdlib>#include <algorithm>#include <queue>#include <map>#include <vector>#define MM(s,q) memset(s,q,sizeof(s))#define INF 0x3f3f3f3f#define MAXN 100005#define Lchild id<<1#define Rchild (id<<1)+1using namespace std;char s[MAXN];int num[MAXN], dp[MAXN][30];void init( int n ) { for ( int i = 1; i <= n; i++ ) dp[i][0] = num[i]; for ( int j = 1; ( 1 << j ) <= n; j++ ) for ( int i = 1; i + ( 1 << j ) - 1 <= n; i++ ) dp[i][j] = min( dp[i][j - 1], dp[i + ( 1 << ( j - 1 ) )][j - 1] );}int RMQ( int i, int j ) { int k = ( int )( log( j - i + 1 ) / log( 2 ) ); return min( dp[i][k], dp[j - ( 1 << k ) + 1][k] );}int main() { int n, q; while ( cin >> n >> q ) { scanf( "%s", s ); int sum = 0; for ( int i = 0; i < n; i++ ) { if ( s[i] == '(' ) sum++; else sum--; num[i + 1] = sum; } init( n ); int a, b; while ( q-- ) { scanf( "%d%d", &a, &b ); int sign = 0; a--, b--; if ( a > b ) swap( a, b ); if ( s[a] == s[b] ) sign = 1; // ( ( 或 ) ) else if ( s[a] == ')' ) sign = 1; // ) ) 或 ) ( else if ( RMQ(a+1,b)>=2 ) sign=1; printf( "%s\n", sign == 1 ? "Yes" : "No" ); } }}
/* 直接暴力 AC:3184ms*/#include <string>#include <cstring>#include <cstdio>#include <cmath>#include <cstdlib>#include <algorithm>#include <queue>#include <map>#include <vector>#define MM(s,q) memset(s,q,sizeof(s))#define INF 0x3f3f3f3f#define MAXN 100005#define Lchild id<<1#define Rchild (id<<1)+1using namespace std;char s[MAXN];int main() { int n, q; while ( cin >> n >> q ) { scanf( "%s", s ); int a, b; while ( q-- ) { scanf( "%d%d", &a, &b ); int sign = 0; a--, b--; if(a>b) swap(a,b); if ( s[a] == s[b] ) sign = 1; // ( ( 或 ) ) else if ( s[a] == ')' ) sign = 1; // ) ) 或 ) ( else { // 只剩下 ( ) swap( s[a], s[b] ); int sum = 0; for ( int i = 0; i < n; i++ ) { if ( s[i] == '(' ) sum++; else sum--; if ( sum < 0 ) break; if ( i == n - 1 ) sign = 1; } swap( s[a], s[b] ); } printf( "%s\n", sign == 1 ? "Yes" : "No" ); } }}
- 括号匹配 RMQ/暴力
- 括号括号括号匹配
- 括号匹配
- 括号匹配
- 括号匹配
- 括号匹配
- 括号匹配/()[]
- 括号匹配
- 括号匹配
- 括号匹配
- 括号匹配
- 括号匹配!!!!
- 括号匹配
- 括号匹配
- 括号匹配
- 括号匹配
- 括号匹配
- 括号匹配
- HDU---1114 Piggy-Bank【完全背包】
- android-view(3)
- NYOJ 260
- 反射
- Kanzi基础---Kanzi基本概念
- 括号匹配 RMQ/暴力
- mysql之简单的多标查询
- C++智能指针详解
- js知识总结
- 【BZOJ】1975 [Sdoi2010]魔法猪学院 k短路(最短路径+A*)
- SSH三大框架的工作原理及流程
- 第一次使用Android Studio时你应该知道的一切配置
- 关系型数据库与非关系型数据库
- LeetCode 435. Non-overlapping Intervals