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 }
  • 相关阅读:
    NetCore指令集和
    在WPF中的Canvas上实现控件的拖动、缩放
    WPF 窗体中的 Canvas 限定范围拖动 鼠标滚轴改变大小
    利用百度API(js),怎样通过地址获取经纬度
    讨论一下hibernate如何动态注册一个动态生成的实体类
    大端序vs小端序
    influxdb+telegraf+grafana实现nginx监控
    python库pillow:实现生成图片并加水印
    mac使用之设置vim colors
    学习python库:elasticsearch-dsl
  • 原文地址:https://www.cnblogs.com/CKboss/p/3420263.html
Copyright © 2011-2022 走看看