给一合法括号序列,交换xy位置的括号问交换后是否合法
解题思路:左扩1右扩-1做前缀和数组
当且仅到pre[i] >= 0 && pre[n] == 0时合法
考虑交换, 若s[x] == s[y]交换无意义
当前为'('后为')'则xy区间内差分值均要减二 所以区间极小值小于2则非法
当前为')'后为'('交换后发现差分值只会变大,且原序列合法,则必然合法
RMQ维护区间极值查询即可
/*
Zeolim - An AC a day keeps the bug away
*/
//#pragma GCC optimize(2)
//#pragma GCC ("-W1,--stack=128000000")
#include <bits/stdc++.h>
using namespace std;
#define mp(x, y) make_pair(x, y)
#define fr(x, y, z) for(int x = y; x < z; ++x)
#define pb(x) push_back(x)
#define mem(x, y) memset(x, y, sizeof(x))
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef std::pair <int, int> pii;
typedef std::vector <int> vi;
//typedef __int128 ill;
const ld PI = acos(-1.0);
const ld E = exp(1.0);
const ll INF = 0x3f3f3f3f;
const ll MOD = 386910137;
const ull P = 13331;
const int MAXN = 1e5 + 10;
char s[MAXN];
int fst[MAXN] = {INF};
int lst[MAXN];
struct rmq
{
int rmq[30][MAXN];
void init(int *arr, int n)
{
for(int i = 0; i < n; ++i)
rmq[0][i] = arr[i];
int len = log2(n) + 1;
for(int i = 1; i < len; ++i)
for(int j = 0; j <= n - (1 << i) + 1; ++j)
rmq[i][j] = min(rmq[i - 1][j], rmq[i - 1][j + (1 << (i - 1) )]);
}
int ask(int fst, int lst)
{
int k = log2(lst - fst + 1);
return min(rmq[k][fst], rmq[k][lst - (1 << k) + 1]);
}
}Q;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
//freopen("d:out.txt","w",stdout);
//freopen("d:in.txt","r",stdin);
int n, m;
while( cin >> n >> m )
{
cin >> s + 1;
fill(fst, fst + n + 10, 0);
for(int i = 1; i <= n; ++i)
fst[i] = fst[i - 1] + (s[i] == '(' ? 1 : -1);
fst[0] = INF; fst[n + 1] = INF;
Q.init(fst, n + 1);
while(m--)
{
int x, y;
cin >> x >> y;
if(x > y)
swap(x, y);
if(s[x] == s[y])
cout << "Yes
";
else
{
bool flag = 1;
if(s[x] == '(')
{
if(Q.ask(x, y - 1) < 2)
flag = 0;
}
if(flag)
cout << "Yes
";
else
cout << "No
";
}
}
}
return 0;
}