博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
V-Parenthesis 前缀+ZKW线段树或RMQ
阅读量:6756 次
发布时间:2019-06-26

本文共 2738 字,大约阅读时间需要 9 分钟。

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

 

 

RMQ:

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

 

 

 

 

 

转载于:https://www.cnblogs.com/Pretty9/p/7347672.html

你可能感兴趣的文章
随笔1
查看>>
HTML中Select的使用具体解释
查看>>
Java synchronized
查看>>
mysql大内存高性能优化方案
查看>>
VSTO 学习笔记(十二)自定义公式与Ribbon
查看>>
[再寄小读者之数学篇](2015-06-24 Series)
查看>>
【Linux】linux常用基本命令
查看>>
4-python学习——数据操作
查看>>
Oracle函数
查看>>
Unity3D学习笔记第一课
查看>>
【redis使用全解析】常见运维操作
查看>>
hdu2377Bus Pass(构建更复杂的图+spfa)
查看>>
Vc6.0打开该文件坠毁
查看>>
[LeetCode] Lowest Common Ancestor of a Binary Search Tree 二叉搜索树的最小共同父节点
查看>>
2015第29周三
查看>>
hdu5024(dp)
查看>>
算法-无向图(连通分量,是否有环和二分图)
查看>>
IOS runtime动态运行时一
查看>>
媒体播放器三大底层架构
查看>>
CCBValue
查看>>