zoukankan      html  css  js  c++  java
  • UESTC 1546 Bracket Sequence

                                        Bracket Sequence
    Time Limit: 3000MS   Memory Limit: 65536KB   64bit IO Format: %lld & %llu

    []   [Go Back]   [Status]  

    Description

    There is a sequence of brackets, which supports two kinds of operations.
    1. we can choose a interval [l,r], and set all the elements range in this interval to left bracket or right bracket. 
    2. we can reverse a interval, which means that for all the elements range in [l,r], if it's left bracket at that time, we change it into right bracket, vice versa.
    Fish is fond of "Regular Bracket Sequence", so he want to know whether a interval [l,r] of the sequence is regular or not after doing some opearations.

    Let us define a regular brackets sequence in the following way: 

    1. Empty sequence is a regular sequence. 
    2. If S is a regular sequence, then (S) is also a regular sequences. 
    3. If A and B are regular sequences, then AB is a regular sequence.

    Input

    In the first line there is an integer T (T≤10), indicates the number of test cases. Each case begins with a line containing an integers N (N ≤ 100,000 and N is a even number), the size of the initial brackets sequence. The next line contains a string whose length is N consisting of '(' and ')'. In the third of each test case, there is an integer M(M ≤ 100,000) indicates the number of queries. Each of the following M lines contains one operation as mentioned below. The index of the bracket sequence is labeled from 0 to N - 1.

    Three operation description:
    set l r c: change all the elements range in [l,r] into '(' or ')'.(c is '(' or ')')
    reverse l r: reverse the interval [l,r]
    query l,r: you should answer that interval [l,r] is regular or not

    Output

    For each test case, print a line containing the test case number (beginning with 1) on its own line, then the answer for each "query" operation, if the interval is regular, print "YES", otherwise print "NO", one on each line.
    Print a blank line after each test case.

    Sample Input

    1
    6
    ((()))
    8
    query 0 5
    set 0 5 (
    query 0 5
    reverse 3 5
    query 0 5
    query 1 4
    query 2 3
    query 0 4

    Sample Output

    Case 1:
    YES
    NO
    YES
    YES
    YES
    NO

    Hint

    Huge input, use "scanf" instead of "cin".

    Source

    Classic Problem
     
    线段树,把左右括号标记成-1,1。。。合法的区间的总和为零,且从左向右的累加和 小于等于 0
    维护每个结点的sum max,为方便reserv再多维护一个min reserv时交换max,min的绝对值再成-1
    set与reserv并存时,要先reserv再set
     
      1 #include <iostream>
      2 #include <cstring>
      3 #include <cstdio>
      4 
      5 #define lson l,m,rt<<1
      6 #define rson m+1,r,rt<<1|1
      7 
      8 using namespace std;
      9 
     10 const int maxn=111111;
     11 
     12 int setv[maxn<<2],rev[maxn<<2],sum[maxn<<2],mx[maxn<<2],mi[maxn<<2];
     13 char str[maxn];
     14 
     15 void reserve(int rt)
     16 {
     17     sum[rt]=-sum[rt];
     18     swap(mx[rt],mi[rt]);
     19     mx[rt]=-mx[rt];
     20     mi[rt]=-mi[rt];
     21     rev[rt]^=1;
     22 }
     23 
     24 void set(int op,int rt,int len)
     25 {
     26     sum[rt]=op*len;
     27     mx[rt]=sum[rt]>0?sum[rt]:0;
     28     mi[rt]=sum[rt]<0?sum[rt]:0;
     29     setv[rt]=op;rev[rt]=0;
     30 }
     31 
     32 void push_down(int rt,int ll,int lr)
     33 {
     34     if(rev[rt])
     35     {
     36         if(setv[rt]) setv[rt]*=-1;
     37         else reserve(rt<<1),reserve(rt<<1|1);
     38         rev[rt]=0;
     39     }
     40     if(setv[rt])
     41     {
     42         set(setv[rt],rt<<1,ll),set(setv[rt],rt<<1|1,lr);
     43         setv[rt]=0;
     44     }
     45 }
     46 
     47 void push_up(int rt)
     48 {
     49     sum[rt]=sum[rt<<1]+sum[rt<<1|1];
     50     mx[rt]=max(mx[rt<<1],sum[rt<<1]+mx[rt<<1|1]);
     51     mi[rt]=min(mi[rt<<1],sum[rt<<1]+mi[rt<<1|1]);
     52 }
     53 
     54 void build(int l,int r,int rt)
     55 {
     56     setv[rt]=rev[rt]=0;
     57     if(l==r)
     58     {
     59         sum[rt]=(str[l]=='(')?-1:1;
     60         mx[rt]=(sum[rt]<0)?0:1;
     61         mi[rt]=(sum[rt]<0)?-1:0;
     62         return;
     63     }
     64     int m=(l+r)>>1;
     65     build(lson),build(rson);
     66     push_up(rt);
     67 }
     68 
     69 void update(int L,int R,int c,int l,int r,int rt)
     70 {
     71     if(L<=l&&r<=R)
     72     {
     73         if(c) set(c,rt,r-l+1);
     74         else reserve(rt);
     75         return ;
     76     }
     77     int m=(l+r)>>1;
     78     push_down(rt,m-l+1,r-m);
     79     if(L<=m) update(L,R,c,lson);
     80     if(R>m) update(L,R,c,rson);
     81     push_up(rt);
     82 }
     83 
     84 int query_sum(int L,int R,int l,int r,int rt)
     85 {
     86     if(L<=l&&r<=R)
     87     {
     88         return sum[rt];
     89     }
     90     int m=(l+r)>>1,ans=0;
     91     push_down(rt,m-l+1,r-m);
     92     if(L<=m) ans+=query_sum(L,R,lson);
     93     if(R>m) ans+=query_sum(L,R,rson);
     94     push_up(rt);
     95     return ans;
     96 }
     97 
     98 int query_max(int L,int R,int l,int r,int rt)
     99 {
    100     if(L<=l&&r<=R)
    101     {
    102         return mx[rt];
    103     }
    104     int m=(l+r)>>1,ret;
    105     push_down(rt,m-l+1,r-m);
    106     if(R<=m) ret=query_max(L,R,lson);
    107     else if(L>m) ret=query_max(L,R,rson);
    108     else ret=max(query_max(L,R,lson),query_sum(L,R,lson)+query_max(L,R,rson));
    109     push_up(rt);
    110     return ret;
    111 }
    112 
    113 int main()
    114 {
    115     int t,cas=1;
    116     char cmd[20];
    117     scanf("%d",&t);
    118     while(t--)
    119     {
    120         int n,m;
    121         printf("Case %d:
    ",cas++);
    122         scanf("%d",&n);
    123         scanf("%s",str);
    124         build(0,n-1,1);
    125         scanf("%d",&m);
    126         while(m--)
    127         {
    128             scanf("%s",cmd);
    129             if(cmd[0]=='s')
    130             {
    131                 int a,b; char c[10];
    132                 scanf("%d%d%s",&a,&b,c);
    133                 if(c[0]=='(')
    134                     update(a,b,-1,0,n-1,1);
    135                 else if(c[0]==')')
    136                     update(a,b,1,0,n-1,1);
    137             }
    138             else if(cmd[0]=='r')
    139             {
    140                 int a,b;
    141                 scanf("%d%d",&a,&b);
    142                 update(a,b,0,0,n-1,1);
    143             }
    144             else if(cmd[0]=='q')
    145             {
    146                 int a,b;
    147                 scanf("%d%d",&a,&b);
    148                 if(!query_sum(a,b,0,n-1,1)&&!query_max(a,b,0,n-1,1)) puts("YES");
    149                 else puts("NO");
    150             }
    151         }
    152         putchar(10);
    153     }
    154     return 0;
    155 }
  • 相关阅读:
    nginx并发数设置_Nginx Ingress 高并发实践
    推荐一个国人开源的推荐系统
    异步并发利器:实际项目中使用CompletionService提升系统性能
    JDK中CompletableFuture类
    mysql日志redo log、undo log、binlog
    <a>标签下载文件 重命名失败 download 无效
    nginx geo黑名单
    夜莺微信报警-V3
    分布式事务的学习
    php实现AES/CBC/PKCS5Padding加密解密(又叫:对称加密)
  • 原文地址:https://www.cnblogs.com/CKboss/p/3420263.html
Copyright © 2011-2022 走看看