题目链接:http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1809

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').

Input

The input contains at most 30 sets. For each set:
The first line contains two integers n,q (2≤n≤10 5,1≤q≤10 5).
The second line contains n characters p 1 p 2…p n.
The i-th of the last q lines contains 2 integers a i,b i (1≤a i,b i≤n,a i≠b i).

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

题意:

现在给出长度为n的一串圆括号串,保证是平衡的括号串;

再给出q个查询,每个查询有两个值a,b,代表询问交换P[a]和P[b],会不会使得括号串变得不平衡。

题解:

首先,我们定义一个preSum数组,代表了这括号序列的前缀和,遇到一个'('就加上1,遇到一个')'就减去1;

这样一来,该括号序列为平衡序列 $\Leftrightarrow$ preSum[n]==0,且对于$\forall$i=1~n都有preSum[i]≥0;

那么我们有以下三种情况:

  1. P[a]==P[b],这样情况显然交换一下和原来没有区别,显然是保持平衡的;
  2. P[a]=')'且P[b]='(',这种情况下,preSum[1]~preSum[a-1]不会有任何变动,preSum[a]~preSum[b-1]都会$+=2$,preSum[b]~preSum[n]也不会有任何变动,这样一来,交换后产生的新的括号序列,依然满足preSum[n]==0,且对于$\forall$i=1~n都有preSum[i]≥0,那么显然该括号序列还是平衡序列;
  3. P[a]='('且P[b]=')',这种情况下,preSum[1]~preSum[a-1]不会有任何变动,preSum[a]~preSum[b-1]都会$-=2$,preSum[b]~preSum[n]不会有任何变动,那么显然关键就在preSum[a]~preSum[b-1]上了,我们知道一旦有一个preSum[i]<0,这个括号序列就不平衡了,所以我们必须保证preSum[a]~preSum[b-1]都大于等于2才行。

所以,我们可以使用线段树或者RMQ维护preSum[]数组的区间最小值,对每次查询只要查询出[a,b]区间内preSum[i]的最小值有没有比2大就可以了。

AC代码:

①线段树:

#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
typedef long long LL; const int maxn=1e5+;
const int INF=0x3f3f3f3f; int n,q;
char str[maxn];
int preSum[maxn]; struct Node{
int l,r;
int val;
}node[*maxn];
void pushup(int root)
{
node[root].val=min(node[root*].val,node[root*+].val);
}
void build(int root,int l,int r)
{
node[root].l=l; node[root].r=r;
if(l==r) node[root].val=preSum[l];
else
{
int mid=l+(r-l)/;
build(root*,l,mid);
build(root*+,mid+,r);
pushup(root);
}
}
int query(int root,int st,int ed)
{
if(ed<node[root].l || node[root].r<st) return INF;
if(st<=node[root].l && node[root].r<=ed) return node[root].val;
else return min(query(root*,st,ed),query(root*+,st,ed));
} int main()
{
while(scanf("%d%d",&n,&q)!=EOF)
{
scanf("%s",str+); preSum[]=;
for(int i=;i<=n;i++) preSum[i]=preSum[i-]+(str[i]=='('?:-); build(,,n);
for(int i=,a,b;i<=q;i++)
{
scanf("%d%d",&a,&b);
if(a>b) swap(a,b); if( str[a]==str[b] || (str[a]==')' && str[b]=='(') ) printf("Yes\n");
else if(query(,a,b-)>=) printf("Yes\n");
else printf("No\n");
}
}
}

②RMQ:

#include<cstdio>
#include<cstring>
#include<vector>
#include<cmath>
using namespace std;
typedef long long LL; const int maxn=1e5+;
const int INF=0x3f3f3f3f; int n,q;
char str[maxn];
int preSum[maxn]; struct _RMQ{
int Mnum[maxn][]; //int(log(maxn)/log(2.0))
void init(int num[])
{
for(int i=;i<=n;i++) Mnum[i][]=num[i];
int j_max=(log(n)/log());
for(int j=;j<=j_max;j++)
{
for(int i=;i<=n;i++)
{
if(i+(<<j)- <= n)
Mnum[i][j]=min(Mnum[i][j-],Mnum[i+(<<(j-))][j-]);
}
}
}
int query(int l,int r)
{
int k=log(r-l+)/log();
return min(Mnum[l][k],Mnum[r-(<<k)+][k]);
}
}RMQ; int main()
{
while(scanf("%d%d",&n,&q)!=EOF)
{
scanf("%s",str+); preSum[]=;
for(int i=;i<=n;i++) preSum[i]=preSum[i-]+(str[i]=='('?:-); RMQ.init(preSum);
for(int i=,a,b;i<=q;i++)
{
scanf("%d%d",&a,&b);
if(a>b) swap(a,b); if( str[a]==str[b] || (str[a]==')' && str[b]=='(') ) printf("Yes\n");
else if(RMQ.query(a,b-)>=) printf("Yes\n");
else printf("No\n");
}
}
}

CSU 1809 - Parenthesis - [前缀和+维护区间最小值][线段树/RMQ]的更多相关文章

  1. 区间最小值 线段树 (2015年 JXNU_ACS 算法组暑假第一次周赛)

    区间最小值 Time Limit : 3000/1000ms (Java/Other)   Memory Limit : 65535/32768K (Java/Other) Total Submiss ...

  2. dutacm.club_1094_等差区间_(线段树)(RMQ算法)

    1094: 等差区间 Time Limit:5000/3000 MS (Java/Others)   Memory Limit:163840/131072 KB (Java/Others)Total ...

  3. tyvj 1038 忠诚 区间最小值 线段树或者rmq

    P1038 忠诚 时间: 1000ms / 空间: 131072KiB / Java类名: Main 描述 老管家是一个聪明能干的人.他为财主工作了整整10年,财主为了让自已账目更加清楚.要求管家每天 ...

  4. CSU 1809 Parenthesis(线段树+前缀和)

    Parenthesis Problem Description: Bobo has a balanced parenthesis sequence P=p1 p2-pn of length n and ...

  5. hdu 5700区间交(线段树)

    区间交 Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submiss ...

  6. Codeforces Round #538 (Div. 2) F 欧拉函数 + 区间修改线段树

    https://codeforces.com/contest/1114/problem/F 欧拉函数 + 区间更新线段树 题意 对一个序列(n<=4e5,a[i]<=300)两种操作: 1 ...

  7. 【题解】P1712 [NOI2016]区间(贪心+线段树)

    [题解]P1712 [NOI2016]区间(贪心+线段树) 一个observe是,对于一个合法的方案,将其线段长度按照从大到小排序后,他极差的来源是第一个和最后一个.或者说,读入的线段按照长度分类后, ...

  8. 【BZOJ4653】【NOI2016】区间(线段树)

    [BZOJ4653][NOI2016]区间(线段树) 题面 BZOJ 题解 \(NOI\)良心送分题?? 既然是最大长度减去最小长度 莫名想到那道反复减边求最小生成树 从而求出最小的比值 所以这题的套 ...

  9. BZOJ_4653_[Noi2016]区间_线段树+离散化+双指针

    BZOJ_4653_[Noi2016]区间_线段树+离散化+双指针 Description 在数轴上有 n个闭区间 [l1,r1],[l2,r2],...,[ln,rn].现在要从中选出 m 个区间, ...

随机推荐

  1. NHibernate 数据查询之Linq to NHibernate

    刚学NHibernate的时候觉得,HQL挺好用的,但是终归没有与其他技术相关联,只有NHibernate用到,一来容易忘记,二来没有智能提示,排除错误什么的都不给力,直到看到一个同事用Linq to ...

  2. Tomcat catalina-deamon.out 日志切割 每天生成一个文件

    Tomcat 使用 jsvc 以守护进程的方式启动(daemon.sh ).这样tomcat自身将会生成另外一个日志文件(catalina-daemon.out),而不是之前的catalina.out ...

  3. 编译Android 必须安装的库

    要安装的库: 正在卸载 build-essential ...正在卸载 g++-multilib ...正在卸载 g++ ...正在卸载 gcc-multilib ...正在卸载 gcc ...正在卸 ...

  4. Lua脚本和C++交互(一)

    现在,越来越多的C++服务器和客户端融入了脚本的支持,尤其在网游领域,脚本语言已经渗透到了方方面面,比如你可以在你的客户端增加一个脚本,这个脚本将会帮你在界面上显示新的数据,亦或帮你完成某些任务,亦或 ...

  5. /etc/fstab文件损坏的补救措施

    最近乱搞,把/etc/fstab弄坏了,导致无法进入图形界面,而且所有文件都是只读的(简直郁闷到底啊),查了好多资料什么的终于弄好了,也走了不少弯路 恩,我不喜欢扯太多东西,这个是补救的帖子,还是希望 ...

  6. Linux下添加FTP账号和服务器、增加密码和用户,更改FTP目录

    1. 启动VSFTP服务器 A:cenos下运行:yum  install  vsftpd B. 登录Linux主机后,运行命令:”service vsftpd start” C. 要让FTP每次开机 ...

  7. 当本机通过代理服务器上网时,本机无法打开在本机上的虚拟机(oracle vm)linux系统上的网站,但是局域网里的其他机器却可以打开

    当本机通过代理服务器上网时,本机无法打开在本机上的虚拟机(oracle vm)linux系统上的网站,但是局域网里的其他机器却可以打开. 只有取消代理,本机才能访问其虚拟机linux系统上的网站

  8. 用js写留言信息的判断非空条件

    首先在tp上有多种方法去判断留言是否为空,但是js是最方便也是最没有冲突的. <form action="{:U('validate')}" method="pos ...

  9. 【盘古分词】Lucene.Net 盘古分词 实现公众号智能自动回复

    盘古分词是一个基于 .net framework 的中英文分词组件.主要功能 中文未登录词识别 盘古分词可以对一些不在字典中的未登录词自动识别 词频优先 盘古分词可以根据词频来解决分词的歧义问题 多元 ...

  10. SharpGL学习笔记(四) 正射投影

    上节谈到投影变换分为透视投影(perspective projection)和正射投影(orthographic projection)两种. 透视投影我们已经介绍过了, 现在谈谈正视投影. 正射投影 ...