csu----G(1809): Parenthesis

 

G(1809): Parenthesis题目

Submit Page    Summary    Time Limit: 5 Sec     Memory Limit: 128 Mb     Submitted: 25     Solved: 7    


Description

Bobo has a balanced parenthesis sequence P=p1 p2…pn of length n and q questions.

The i-th question is whether P remains balanced after pai and pbi  swapped. Note that questions are individual so that they have no affect on others.

Parenthesis sequence S is balanced if and only if:

1. S is empty;

2. or there exists balanced parenthesis sequence A,B such that S=AB;

3. or there exists balanced parenthesis sequence S' such that S=(S').

Input

The input contains at most 30 sets. For each set:

The first line contains two integers n,q (2≤n≤105,1≤q≤105).

The second line contains n characters p1 p2…pn.

The i-th of the last q lines contains 2 integers ai,bi (1≤ai,bi≤n,ai≠bi).

 

Output

For each question, output "Yes" if P remains balanced, or "No" otherwise.

Sample Input

4 2
(())
1 3
2 3
2 1
()
1 2

Sample Output

No
Yes
No

这个代码主要是为了熟悉一下树状数组的运用。

#include<cstdio>
#include<cstring>
using namespace std;
#define MAXN 100005
int s[MAXN];
char st[100005];
int n;
int lowbit(int x){return x&(-x);}
int sum(int x){
    int sum=0;
    while(x){
        sum+=s[x];
        x-=lowbit(x);
    }
    return sum;
}
void add(int x,int a){
    while(x<=n){
        s[x]+=a;
        x+=lowbit(x);
    }
}
int main()
{
    int q;
    while(~scanf("%d%d",&n,&q))
    {
        memset(s,0,sizeof(s));
        scanf("%s",st);
        for(int i=1;i<=n;i++)
        {
            if(st[i-1]=='(')
                add(i,1);
            else
                add(i,-1);
        }
        int a,b;
        while(q--)
        {
            scanf("%d%d",&a,&b);
            bool flag=true;
            if(a>b)
            {
                a=a+b;
                b=a-b;
                a=a-b;
            }
            if(st[a-1]=='('&&st[b-1]==')')
            {
                while(a<b)
                {
                    if(sum(a)-2<0)
                    {
                        flag=false;
                        break;
                    }
                    a++;
                }
            }
            if(flag==false)
                printf("No\n");
            else
                printf("Yes\n");
        }
    }
    return 0;
}

 普通求和,比上面的代码优化了好多倍

#include<iostream>
using namespace std;
#define MAXN 100005
int sum[MAXN];
char s[MAXN];
int main()
{
    int n,q;
    int a,b;
    while(~scanf("%d%d",&n,&q))
    {
        getchar();
        for(int i=1;i<=n;i++)
        {
            scanf("%c",&s[i]);
            if(s[i]=='(')
                sum[i]=sum[i-1]+1;
            else
                sum[i]=sum[i-1]-1;
        }
        while(q--)
        {
            scanf("%d%d",&a,&b);
            if(a>b)
            swap(a,b);
            bool flag=true;
            if(s[a]=='('&&s[b]==')')
            for(int i=a;i<b;i++)
            {
                if(sum[i]<2)
                {
                    flag=false;
                    break;
                }
            }
            if(flag)
                printf("Yes\n");
            else
                printf("No\n");
        }
    }
    return 0;
}

 线段树优化,区间最小,比上面代码好

#include<cstdio>
#include<algorithm>
#define INF 100005
#define MAXN 100005
using namespace std;
struct
{
    int l,r;
    int min;
}tree[MAXN<<2];
int sum[MAXN];
char st[MAXN];
void BuildTree(int i,int L,int R)
{
    tree[i].l=L;
    tree[i].r=R;
    if(L==R)
    {
        tree[i].min=sum[L];
        return ;
    }
    BuildTree(i<<1,L,(L+R)>>1);
    BuildTree(i<<1|1,((L+R)>>1)+1,R);
    tree[i].min=min(tree[i<<1].min,tree[i<<1|1].min);
    return ;
}
int QueryTree(int L,int R,int i)
{
    if(L<=tree[i].l&&R>=tree[i].r)
    {
        return tree[i].min;
    }
    int mi=INF;
    if(L<=tree[i<<1].r)
        mi=QueryTree(L,R,i<<1);
    if(R>=tree[i<<1|1].l)
        mi=min(mi,QueryTree(L,R,i<<1|1));
    return mi;
}
int main()
{
    int n,q,l,r;
    while(~scanf("%d%d",&n,&q))
    {
        sum[0]=0;
        scanf("%s",st);
        for(int i=1;i<=n;i++)
        {
            if(st[i-1]=='(')
                sum[i]=sum[i-1]+1;
            else
                sum[i]=sum[i-1]-1;
        }
        BuildTree(1,1,n);
        while(q--)
        {
            scanf("%d%d",&l,&r);
            if(l>r)
                swap(l,r);
            if(st[l-1]=='('&&st[r-1]==')'&&QueryTree(l,r-1,1)<2)
                printf("No\n");
            else
                printf("Yes\n");
        }
    }
    return 0;
}

 

posted @ 2018-08-16 20:29  ke_yi  阅读(156)  评论(0编辑  收藏  举报