CSU-1809:Parenthesis 括号匹配问题(线段树维护最小值)

题面链接

题意

已知一个只含 ‘(’ 和 ‘)’ 的完美匹配的字符串,交换两个位置的字符是否能够完美匹配,如果能输出“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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值