zoukankan      html  css  js  c++  java
  • Parenthesis

     
    G - Parenthesis
    Time Limit:5000MS     Memory Limit:131072KB     64bit IO Format:%lld & %llu

    Description

    Bobo has a balanced parenthesis sequence P=p 1 p 2…p n of length n and q questions.
    The i-th question is whether P remains balanced after p ai and p bi  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≤10 5,1≤q≤10 5).
    The second line contains n characters p 1 p 2…p n.
    The i-th of the last q lines contains 2 integers a i,b i (1≤a i,b i≤n,a i≠b i).

    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

    Hint

     思路:线段树;
     当括号匹配时我们有所有的前缀和sum〉=0;那么当我们交换两个括号时仅会改变sum[a]----sum[b]的值 ,并且只有当a为(  b为 )才可能不匹配,那么当这两交换,这个区间段所有的值会减去2,那么我们用线段树维护sum的最小值即可,然后与2比较。复杂n*log(n)
     1 #include<stdio.h>
     2 #include<algorithm>
     3 #include<iostream>
     4 #include<queue>
     5 #include<stdlib.h>
     6 #include<string.h>
     7 using namespace std;
     8 char str[100005];
     9 int tree[100005*4];
    10 int ans[100005];
    11 void build(int l,int r,int k);
    12 int ask(int l,int r,int k,int nn,int mm);
    13 int main(void)
    14 {
    15     int n,m;
    16     while(scanf("%d %d",&n,&m)!=EOF)
    17     {
    18         scanf("%s",str);
    19         int l = strlen(str);
    20         ans[0] = 0;
    21         for(int i = 0; i < l; i++)
    22         {
    23             if(str[i] == '(')
    24             {
    25                 ans[i+1] = 1;
    26             }
    27             else ans[i+1] = -1;
    28         }
    29         for(int i = 1; i <= l; i++)
    30         {
    31             ans[i] = ans[i] + ans[i-1];
    32         }
    33         build(1,l,0);
    34         while(m--)
    35         {
    36             int x,y;
    37             scanf("%d %d",&x,&y);
    38             if(x > y)swap(x,y);
    39             if(str[x-1]==str[y-1]||str[x-1]==')')
    40             {
    41                 printf("Yes
    ");
    42             }
    43             else
    44             {
    45                 int ak = ask(x,y-1,0,1,l);
    46                 if(ak<2)
    47                     printf("No
    ");
    48                 else printf("Yes
    ");
    49             }
    50         }
    51     }return 0;
    52 }
    53 void build(int l,int r,int k)
    54 {
    55     if(l == r)
    56     {
    57         tree[k] = ans[l];
    58     }
    59     else
    60     {
    61         build(l,(l+r)/2,2*k+1);
    62         build((l+r)/2+1,r,2*k+2);
    63         tree[k] = min(tree[2*k+1],tree[2*k+2]);
    64     }
    65 }
    66 int ask(int l,int r,int k,int nn,int mm)
    67 {
    68     if(nn>r||mm<l)
    69     {
    70       return 1e9;
    71     }
    72     else if(l<=nn&&r>=mm)
    73     {
    74         return tree[k];
    75     }
    76     else
    77     {
    78         int x = ask(l,r,2*k+1,nn,(nn+mm)/2);
    79         int y = ask(l,r,2*k+2,(nn+mm)/2+1,mm);
    80         return min(x,y);
    81     }
    82 }
     
    油!油!you@
  • 相关阅读:
    经典网络命令(搜集、概括)
    浅谈“五万月薪涉足数据恢复行业”
    C语言宏定义技巧(常用宏定义)
    安装IIS5.0出错
    IDM(Internet Download Manager)下载
    tape记忆法
    华为手环更换绑定手机
    冯况 | 清理电脑磁盘
    利用知网查个人信息
    双向循环链表
  • 原文地址:https://www.cnblogs.com/zzuli2sjy/p/5870025.html
Copyright © 2011-2022 走看看