Yet Another Bracket Sequence(线段树)

题目描述
One day, Little Gyro was playing with a series of Bracket Sequences, A Bracket Sequence is a string that only contains two kinds of characters ‘(’ and ‘)’. Let us define a regular Bracket Sequence in the following way:
Empty sequence is a regular sequence.
If S is a regular sequence, then (S) is also a regular sequence.
If A and B are regular sequences, then A+B (the character ‘+’ means splice the sequence A and B) is a regular sequence.
For example, all of the following sequences of characters are regular Bracket Sequences: (), (());
And all of the following character sequences are not: (, ), )(, ())), ((();
After randomly picking a Bracket Sequence from the series, Little Gyro was currently studying whether the selected Bracket Sequence is regular or not. While Little Gyro was carefully investigating the sequence, the naughty boy Onlystar came and changed some brackets at several specific positions. For each operation, the left bracket ‘(’ will be replaced to the right bracket ‘)’, and the right bracket ‘)’ will be replaced to the left bracket ‘(’ as well. All the operations will not alter the length of the whole Bracket Sequence.
It was really annoying that Little Gyro had to calculate the whole Bracket Sequence again and again. However, the troublemaker Onlystar thought that it was very funny.
Now Little Gyro send this task to you, after each step of Onlystar’s operation, please tell Little Gyro whether the current Bracket Sequence is regular or not. Please help him.

输入描述:
Each input file only contains one test case.
The first line contains two integers n and m (1 ≤ n, m ≤ 105 ), indicating the length of the given Bracket Sequence and the times of Onlystar change the Bracket Sequence.
The second line contains a string S and its length is n, indicating the given Bracket Sequence.
Then, the following m lines, each line contains a integer x (1 ≤ x ≤ n), indicating the position that Onlystar will change the Bracket Sequence, it means ‘(’ will replace to ‘)’ and ‘)’ will replace to ‘(’.

输出描述:
For each position, output “Yes” (without quotes) in a line if the Bracket Sequence is a regular Bracket Sequence after this operation. Otherwise, output “No” (without quotes) instead.

示例1
输入
6 5
((())(
6
3
4
1
6

输出
Yes
No
Yes
No
No

思路
对每一个括号序列,分别对左括号和右括号维护线段树,每次更新后确认[1,n]之间是否存在多余的括号就行,线段树中判断每个区间左右括号是否能够结合,如果(1,n)的区间能完美结合,那么两个线段树的(1,n)的区间内就不会有多余的括号,表现在整个线段树上就是Tr[1]==0 && Tl[1]==0

代码实现

#pragma GCC optimize(3,"Ofast","inline")
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=1e5+5;
const int M=20016;
const int INF=0x3f3f3f3f;
const ll LINF=1e18;
const ull sed=31;
const ll mod=998244353;
const double eps=1e-5;
const double PI=acos(-1.0);
typedef pair<int,int>P;
typedef pair<double,double>Pd;
   
template<class T>void read(T &x)
{
    x=0;int f=0;char ch=getchar();
    while(ch<'0'||ch>'9') {f|=(ch=='-');ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    x=f?-x:x;
    return;
}

int n,q;
char s[N];
int Tr[N<<2],Tl[N<<2];

void pushup(int rt)
{
    int t=min(Tl[rt<<1],Tr[rt<<1|1]);
    Tl[rt]=Tl[rt<<1]+Tl[rt<<1|1]-t;
    Tr[rt]=Tr[rt<<1]+Tr[rt<<1|1]-t;
}

void build(int rt,int l,int r)
{
    if(l==r)
    {
        if(s[l]=='(') Tl[rt]=1;
        else Tr[rt]=1;
        return ;
    }
    int mid=(l+r)>>1;
    build(rt<<1,l,mid);
    build(rt<<1|1,mid+1,r);
    pushup(rt);
}

void update(int p,int rt,int l,int r)
{
    if(l==r)
    {
        Tr[rt]^=1;
        Tl[rt]^=1;
        return ;
    }
    int mid=(l+r)>>1;
    if(mid>=p) update(p,rt<<1,l,mid);
    else update(p,rt<<1|1,mid+1,r);
    pushup(rt);
}
int main()
{
    //freopen("a.txt","r",stdin);
    read(n);read(q);
    scanf("%s",s+1);
    build(1,1,n);
    while (q--)
    {
        int x;
        read(x);
        update(x,1,1,n);
        if(Tr[1] || Tl[1]) puts("No");
        else puts("Yes");
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值