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\n");
42             }
43             else
44             {
45                 int ak = ask(x,y-1,0,1,l);
46                 if(ak<2)
47                     printf("No\n");
48                 else printf("Yes\n");
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 }

 

 

转载于:https://www.cnblogs.com/zzuli2sjy/p/5870025.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值