用线段树处理前缀’(‘不平衡个数,交换之后,若依旧平衡那么在【 l -> r-1】区间的
前缀和会-2 ,因为左边’(‘贡献-1 , 较缓过来右边’)’消耗-1 ,因此区间内前缀和均-2 。
因此, 若在交换之前【 l -> r-1】区间的前缀和存在小于2 , 那么交换完便出现负数现象, 即有区间不平衡, 那么即是非法的
侵权删
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
const int N = 1e5 + 5;#define lson i<<1,l,mid
#define rson i<<1|1,mid+1,rint sum[N*3],val[N];
char s[N];void push_up(int i)
{sum[i] = min(sum[i<<1],sum[i<<1|1]);
}void build(int i,int l,int r)
{if(l==r){sum[i] = val[l];return;}int mid = (l+r) >> 1;build(lson);build(rson);push_up(i);
}int querry(int i,int l,int r,int L,int R)
{if(L<=l && R>=r)return sum[i];int ans = 100000000;int mid = (l+r) >> 1;if(L<=mid)ans = min(ans,querry(lson,L,R));if(R>mid) ans = min(ans,querry(rson,L,R));return ans;
}int main()
{//freopen("in.txt","r",stdin);//freopen("out.txt","w",stdout);ios::sync_with_stdio(0);cin.tie(0);int n,m;while(~scanf("%d%d",&n,&m)){scanf("%s",s+1);for(int i=1;i<=n;i++){if(s[i]=='(')val[i] = val[i-1] + 1;else val[i] = val[i-1] - 1;}build(1,1,n);while(m--){int l,r;scanf("%d%d",&l,&r);if(l>r)swap(l,r);if(s[l]=='(' && s[r]==')'){if(querry(1,1,n,l,r-1)<2)printf("No\n");else printf("Yes\n");}else printf("Yes\n");}}return 0;
}