题意
已知一个只含 ‘(’ 和 ‘)’ 的完美匹配的字符串,交换两个位置的字符是否能够完美匹配,如果能输出“Yes”,否则“No”。
输入
输入n和q表示字符串的长度为n,有q次询问,接下来输入这个字符串,再输入q组(l,r)表示交换 l 和 r。
分析
首先对字符串处理,“(”赋值为1,“)”赋值为-1 。
预处理出赋值后字符串的前缀和sum[i]。
如果s[l]==s[r]或者s[l]==’)’&&s[r]==’(‘这两种情况是一定能在交换后完美匹配
当s[l]==’(‘&&s[r]==’)’这时候交换之后整个区间的前缀和会 -2,我们只需要判断区间最小值 -2 之后是否 >=0.如果满足输出“Yes”,否则“No”。
问题
在遇到这个题的时候没有仔细分析,其实并不是很难的题,但在比赛的时候就完全想不出来,太不冷静了,遇到第一个题懵逼了之后就没有勇气去写其他题了,太没有状态了,忘长记性能改正!!!!!!!!!
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
char s[maxn];
int sum[maxn];
int n,q,l,r,i,j;
struct node
{
int l,r,minn;
}tr[maxn*4];//一定要*4
void build(int id,int l,int r)
{
tr[id].l=l;
tr[id].r=r;
if(l==r)
{
tr[id].minn=sum[l];
}
else
{
int mid=(l+r)/2;
build(id*2,l,mid);
build(id*2+1,mid+1,r);
tr[id].minn=min(tr[id*2].minn,tr[id*2+1].minn);
}
}
int quary(int id,int l,int r)
{
if(l<=tr[id].l&&tr[id].r<=r)
return tr[id].minn;
else
{
int mid=(tr[id].l+tr[id].r)/2;
if(r<=mid)
return quary(id*2,l,r);
else if(l>mid)
return quary(id*2+1,l,r);
else
{
int x=quary(id*2,l,r);
int y=quary(id*2+1,l,r);
return min(x,y);
}
}
}
int main()
{
while(~scanf("%d%d",&n,&q))
{
int ans=0;
scanf("%s",s+1);
if(s[1]='(') sum[1]=1;
else sum[1]=-1;
for(i=2;i<=n;i++)
{
if(s[i]=='(')
sum[i]=sum[i-1]+1;
else
sum[i]=sum[i-1]-1;
}
build(1,1,n);
for(i=0;i<q;i++)
{
scanf("%d%d",&l,&r);
if(l>r) swap(l,r);
if(s[l]=='('&&s[r]==')')
{
if(quary(1,l,r-1)-2>=0)
printf("Yes\n");
else
printf("No\n");
}
else printf("Yes\n");
}
}
return 0;
}