这个题,给你一串括号序列 问你交换 ai,bi两个位置的括号,原串是否依然匹配
题目分析,对于一个括号序列,我们只要找到一个右括号,在它之前没有左括号与它匹配,那么就是不匹配的序列,将左括号记为-1 右括号记为1 求前缀和 如果前缀和 >=1 那么一定就不匹配了
由于有很多查询,所以,我们用Rmq 求 [ai,bi) 区间最大值, 只有在ai 和bi 是 从 “(” 和”)” 换成“)”“(”时,采用可能会从匹配变成不匹配,那么交换后 [ai,bi)区间内的数都会+2 ,我们只要求区间最大 +2是否>=1 即可
//这个题wa了很多次,因为我理所应当把 ai
#include <iostream>
#include <cstdio>
#include <vector>
#include <string>
#include <cstring>
#define cl(a) memset(a,0,sizeof(a))
using namespace std;
const int maxn=1e5+50;
const int mod=1e9+7;
const int inf=0x3f3f3f3f;
typedef long long LL;
int st[maxn];
int d[maxn][18];
int n,q;
void predig()
{
memset(d,-inf,sizeof(d));
for (int i = 1; i<=n; i++)
{
d[i][0] = st[i];
}
for (int j = 1; (1 << j) <= n; j++)
{
for (int i = 1; (i + (1 << j) - 1)<=n; i++)
{
d[i][j] = max(d[i][j - 1], d[i + (1 << (j - 1))][j - 1]);
}
}
}
int rmq(int l, int r)
{
int k = 0;
while (1 << (k + 1) <= (r - l + 1)) k++;
return max(d[l][k], d[r - (1 << k) + 1][k]);
}
int main()
{
while(scanf("%d%d",&n,&q)!=EOF)
{
cl(st);
string s;
cin>>s;
for(int i=0;i<s.size();i++)
{
if(s[i]=='(')st[i+1]=st[i]-1;
else st[i+1]=st[i]+1;
}
predig();
for(int i=1;i<=q;i++)
{
int ai,bi;
scanf("%d%d",&ai,&bi);
if (ai > bi) swap (ai,bi);
int t=rmq(ai,bi-1);
//cout<<t<<endl;XA
if(s[bi-1]==')'&&s[ai-1]=='(')t+=2;
if(t>=1) puts("No");
else puts("Yes");
}
}
return 0;
}