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;
    }
  • 相关阅读:
    通用权限管理设计 之 数据库结构设计
    jQuery LigerUI 插件介绍及使用之ligerDateEditor
    jQuery LigerUI 插件介绍及使用之ligerTree
    jQuery LigerUI V1.01(包括API和全部源码) 发布
    jQuery liger ui ligerGrid 打造通用的分页排序查询表格(提供下载)
    jQuery LigerUI V1.1.5 (包括API和全部源码) 发布
    jQuery LigerUI 使用教程表格篇(1)
    jQuery LigerUI V1.0(包括API和全部源码) 发布
    jQuery LigerUI V1.1.0 (包括API和全部源码) 发布
    nginx keepalived
  • 原文地址:https://www.cnblogs.com/ke-yi-/p/10175816.html
Copyright © 2011-2022 走看看