uestc 1546 括弧序列 區間線段樹

來源:互聯網
上載者:User

/*
    區間線段樹  區間覆蓋   括弧序列  lazy

    題意:給一串括弧序列,問[l,r]的括弧序列是否合法。合法的定義:1,Empty 2,S合法,則(S)合法 3,A和B合法,則AB合法。有兩種操作,一種一般區間修改(reverse, set),還有Query.

    思路:之前一遇到括弧序列就跪,因為我到現在都搞不清楚what is regular brackets sequence...
          所以在大牛blog上看到下面這句話的時候心情很激動~~from : http://hi.baidu.com/zyz913614263/item/ed68843a6839ecd2392ffa2b
           *** "把左括弧當做-1,右括弧當做1,對於一個區間,只要從左至右的和的最大值為0,並且區間的和為0,則這個區間就是完全符合的" ***

          知道上面這個定理後,接下來都是自己寫的。這道題細節還是挺多的。

          (1)在Update和Query下子節點時,都要先put_down。
          (2)我的lazy標記只有一個,後來看別人的代碼時發現他們用了兩個,一個is_reverse, 一個is_set。其實可以合成一個的。
          (3)細節多WA在有lazy來時和put_down的時候的處理:儲存lazy時要更新節點屬性put_self。剛開始時我把更新lazy值和更新節點屬性分開了,後來發現不對,前後的lazy值會影響節點屬性的更新,所以乾脆都扔到change()裡,方便多了。

           *** "把左括弧當做-1,右括弧當做1,對於一個區間,只要從左至右的和的最大值為0,並且區間的和為0,則這個區間就是完全符合的" ***

*/


//Bracket Sequence UESTC 1546#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;#define     debug       printf("!\n")#define     MAXN        100005#define     MID(x, y)   (((x)+(y)) >> 1)#define     L(x)        ((x)<<1)#define     R(x)        (((x)<<1)|1)typedef pair<int,int> Pair;struct Node {    int l,r,min,max,end;    char lazy;} f[MAXN << 2];char str[100005];int n;void Update(int , int , int , char);void put_self(int u, char op)           //更新節點u{    if(op == '(' || op == ')') {        int tmp = (op == '(' ? -1 : 1);        f[u].end = tmp * (f[u].r - f[u].l + 1);        f[u].min = min(tmp, f[u].end);        f[u].max = max(tmp, f[u].end);    } else {        f[u].end = - f[u].end;        int tmp = f[u].max;        f[u].max = -f[u].min;        f[u].min = -tmp;    }}void change(int u, char arrive)     //遇到修改[l,r]操作時邊lazy,邊更新自己的屬性(max,min,end){    if(arrive == '(' || arrive == ')') {        put_self(u, arrive);        f[u].lazy = arrive;    } else if(arrive == 'r') {        put_self(u, 'r');        if(f[u].lazy == 'r') f[u].lazy = '\0';        else if(f[u].lazy == '\0') f[u].lazy = 'r';        else f[u].lazy = (f[u].lazy == ')' ?  '(' : ')');    }}void put_up(int u){    Node & ll = f[L(u)];    Node & rr = f[R(u)];    f[u].end = ll.end + rr.end;    f[u].max = max(ll.max, ll.end+rr.max);    f[u].min = min(ll.min, ll.end+rr.min);}void put_down(int u){    int mid = MID(f[u].l, f[u].r);    Update(L(u), f[u].l, mid, f[u].lazy);    Update(R(u), mid+1, f[u].r, f[u].lazy);    f[u].lazy = '\0';}void build(int u, int l, int r){    f[u].l = l, f[u].r = r, f[u].lazy = '\0';        if(l == r) {        f[u].min = f[u].max = f[u].end = (str[l] == '(' ? -1 : 1);      //小錯誤大煩惱,忘了初始化min...debug了好久        return ;    }    int mid = MID(l, r);    build(L(u), l, mid);    build(R(u), mid+1, r);    put_up(u);}Pair Query(int u, int l, int r){    if(l == f[u].l && f[u].r == r) {        return Pair (f[u].end, f[u].max);    }    if(f[u].lazy != '\0') put_down(u);          //所以說,小錯誤有大關係...漏了判斷就得debug很久    int mid = MID(f[u].l, f[u].r);    if(r <= mid) return Query(L(u), l, r);    else if(mid < l) return Query(R(u), l, r);    else {        Pair p1 = Query(L(u), l, mid) , p2 = Query(R(u), mid+1, r);        return Pair(p1.first + p2.first, max(p1.second, p1.first + p2.second));    }}void Update(int u, int l, int r, char op){    if(l == f[u].l && f[u].r == r) {        change(u, op);          //把lazy的更新,max/end的更新放到change裡了        return ;    }    if(f[u].lazy != '\0')put_down(u);    int mid = MID(f[u].l, f[u].r);    if(r <= mid) Update(L(u), l, r, op);    else if(mid < l) Update(R(u), l, r, op);    else Update(L(u), l, mid, op), Update(R(u), mid+1, r, op);    put_up(u);}int main(){    int cases, Cas = 0, query, l, r;    char op[10];    scanf("%d", &cases);    while(cases--) {        printf("Case %d:\n", ++Cas);        scanf("%d%s%d", &n, str, &query);        build(1, 0, n-1);        while(query--) {            scanf("%s%d%d\n", op, &l, &r);            if(op[0] == 'q') {                Pair p = Query(1, l,r);                puts(p.first == 0 && p.second < 1 ? "YES" : "NO");//                printf("!! %d  %d\n", p.first, p.second);            } else if(op[0] == 's') {                scanf("%s", str);                Update(1, l, r, str[0]);            } else Update(1, l, r, 'r');        }        puts("");    }    return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.