Bobo has a balanced parenthesis sequence P=p 1 p 2…p n of length n and q questions.
The i-th question is whether P remains balanced after p ai and p bi  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').

题意就是给出一个正确配对的括号序列,问交换两个括号以后是否依旧正确配对,一般括号配对都可以使用遇到左括号加一,遇到右括号减一的方法,中间过程中不能出现负值,否则配对失败,这道题也可以这样做,先求出前缀和,如:

编号: 1    2   3  4   5   6    7   8

         (    (    (    )    )    )    (    )

前缀: 1   2    3  2   1   0     1  0

有两种仍然可以配对的交换:1.当交换的两个括号相同时,2.ai是右括号,bi是左括号时,根据示例可以看出;

唯一一种可能发生不配对的交换:ai是左括号,bi是右括号;当有右括号加入ai位置时,从ai位置到bi-1位置的前缀和全部都要减2,所以ai到bi-1区间内最小值至少为2,这样就变成了查询区间最小值问题了,可以用线段树,也可以RMQ(代码待补);因为刚刚学习线段树,又刚好听说ZKW线段树代码比较精简,所以临时现去学习了一下,结果发现好多给的示例代码都是错的。。。这个版本可能也有错,但是AC了就好。。。哈哈哈哈哈哈哈哈哈嗝。。。。

zkw线段树:

#include<iostream>
#include<cstring>
#include<cstdio> using namespace std; const int N = + ;
const int INF = (<<);
int sum[N],T[N<<],cnt,M;
char ch[N]; void Build(int n){
int i;
for(M=;M<=n+;M*=);
for(i=+M;i<=n+M;i++) T[i] = sum[cnt++];
for(i=M-;i;i--) T[i]=min(T[i<<],T[i<<|]);
} void Update(int n,int V){
for(T[n+=M]=V,n/=;n;n/=)
T[n]=min(T[n<<],T[n<<|]);
} int Query(int s,int t){
int minc=INF;
for(s=s+M-,t=t+M+;s^t^;s/=,t/=){
if(~s&) minc=min(minc,T[s^]);
if(t&) minc=min(minc,T[t^]);
}
return minc;
}
int main(){
int n,q,a,b;
while(scanf("%d %d",&n,&q)==){
scanf("%s",ch+);
sum[] = ;
for(int i=;i<=n;i++){
if(ch[i]=='(') sum[i]=sum[i-]+;
else sum[i]=sum[i-]-;
}
cnt = ;
Build(n);
for(int i=;i<q;i++){
scanf("%d %d",&a,&b);
if(a > b) swap(a,b);
if(ch[a]==ch[b] || (ch[a]==')'&&ch[b]=='(')){ printf("Yes\n"); continue; }
int ret = Query(a,b-);
printf("%s\n",ret>=?"Yes":"No");
}
}
return ;
}


RMQ:

#include<iostream>
#include<cstring>
#include<cstdio> using namespace std; const int N = + ;
const int INF = (<<);
int sum[N],dp[N][],cnt,n;
char ch[N];
void RMQ_Init(){
memset(dp,,sizeof(dp));
for(int i=;i<n+;i++) dp[i][] = sum[i];
for(int j=;(<<j)<=n+;j++)
for(int i=;i+(<<j)- < n+;i++)
dp[i][j] = min(dp[i][j-],dp[i+(<<(j-))][j-]);
}
int RMQ(int L,int R){
int k = ;
while((<<(k+))<=R-L+) k++;
return min(dp[L][k],dp[R-(<<k)+][k]);
}
int main(){
int q,a,b;
while(scanf("%d %d",&n,&q)==){
scanf("%s",ch+);
sum[] = ;
for(int i=;i<=n;i++){
if(ch[i]=='(') sum[i]=sum[i-]+;
else sum[i]=sum[i-]-;
}
cnt = ;
RMQ_Init();
for(int i=;i<q;i++){
scanf("%d %d",&a,&b);
if(a > b) swap(a,b);
if(ch[a]==ch[b] || (ch[a]==')'&&ch[b]=='(')){ printf("Yes\n"); continue; }
int ret = RMQ(a,b-);
printf("%s\n",ret>=?"Yes":"No");
}
}
return ;
}
 


最新文章

  1. sqlserver事务加锁机制
  2. synchronized使用说明
  3. IO is frozen on database xxx, No user action is required
  4. Badboy使用数据源Excel进行脚本参数化
  5. 【C#】Json数据 排版算法
  6. CentOS 6.6 yum 方式安装sunversion 服务器
  7. multi2sim,booksim简介
  8. android 开发不能创建目录
  9. POJ3261-哈希
  10. Cocos2d-x 2.1.5 简单动画
  11. 使用myeclipse新建和删除web项目时一定要小心
  12. ConcurrentHashMap源码分析
  13. let内嵌lambda使用set!构成闭包
  14. 基于SSL实现Mysql加密主从
  15. 编译QFileSystemModel
  16. LeetCode--437--路径总和3
  17. Hbase访问方式
  18. CentOS下搭建Hadoop
  19. mybatis介绍——(一)
  20. 如何:声明、实例化和使用委托(C# 编程指南)

热门文章

  1. Python---进阶---文件操作---比较文件不同
  2. 【hackerrank】Type of Triangle
  3. appium环境666
  4. Java大文件上传详解及实例代码
  5. R 动态定义变量名 assign
  6. es之java各种查询操作
  7. foreach(增强for循环)和for的区别
  8. HTML To Word
  9. img下面出现了蜜汁空白
  10. 2019 Nanchang Onsite