zoukankan      html  css  js  c++  java
  • 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
    ");
                else
                    printf("Yes
    ");
            }
        }
        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
    ");
                else
                    printf("No
    ");
            }
        }
        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
    ");
                else
                    printf("Yes
    ");
            }
        }
        return 0;
    }
  • 相关阅读:
    Template-网页模板:百科
    POJ 1743 Musical Theme(后缀数组)
    android ProgressBar 样式讲解
    opencv显示鼠标所在位置的rgb值
    JSU 2013 Summer Individual Ranking Contest
    spring mvc 中文乱码 post与get的方法解决
    iphone/ipad实现自定义的开关UISwitch(continuous,clipsToBounds,userInteractionEnabled属性)
    hdu 2093
    poj 1180 斜率优化dp
    太空飞行计划问题
  • 原文地址:https://www.cnblogs.com/ke-yi-/p/10175816.html
Copyright © 2011-2022 走看看