zoukankan      html  css  js  c++  java
  • BZOJ 2329: [HNOI2011]括号修复( splay )

    把括号序列后一定是))))((((这种形式的..所以维护一个最大前缀和l, 最大后缀和r就可以了..答案就是(l+1)/2+(r+1)/2...用splay维护,O(NlogN). 其实还是挺好写的, 只是我傻X

    --------------------------------------------------------------------------------

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
     
    using namespace std;
     
    const int maxn = 100009;
     
    struct Node* Null;
     
    struct Node {
    Node *p, *ch[2];
    int s, v;
    int lmn, lmx, rmn, rmx, sm;
    int tg;// tg 1) -1(
    bool rev, inv;
    inline void Clr() {
    lmn = lmx = rmn = rmx = sm = s = v = tg = rev = inv = 0;
    }
    inline bool d() {
    return this == p->ch[1];
    }
    inline void setc(Node* t, int c) {
    ch[c] = t;
    t->p = this;
    }
    inline void Tg(int v) {
    tg = v;
    rev = inv = false;
    }
    inline void Rev() {
    rev ^= 1;
    }
    inline void Inv() {
    inv ^= 1;
    }
    inline void pushDown() {
    if(tg) {
    v = tg;
    for(int i = 0; i < 2; i++)
    if(ch[i] != Null) ch[i]->Tg(tg);
    tg = 0;
    }
    if(rev) {
    swap(ch[0], ch[1]);
    for(int i = 0; i < 2; i++)
    if(ch[i] != Null) ch[i]->Rev();
    rev = false;
    }
    if(inv) {
    v = -v;
    for(int i = 0; i < 2; i++)
    if(ch[i] != Null) ch[i]->Inv();
    inv = false;
    }
    for(int i = 0; i < 2; i++)
    if(ch[i] != Null) ch[i]->upd();
    }
    inline void upd() {
    lmx = max(ch[0]->lmx, ch[0]->sm + max(0, v + max(0, ch[1]->lmx)));
    rmx = max(ch[1]->rmx, ch[1]->sm + max(0, v + max(0, ch[0]->rmx)));
    lmn = min(ch[0]->lmn, ch[0]->sm + min(0, v + min(0, ch[1]->lmn)));
    rmn = min(ch[1]->rmn, ch[1]->sm + min(0, v + min(0, ch[0]->rmn)));
    sm = ch[0]->sm + v + ch[1]->sm;
    s = ch[0]->s + 1 + ch[1]->s;
    if(tg) {
    sm = tg * s;
    lmx = max(0, sm);
    rmx = max(0, sm);
    lmn = min(0, sm);
    rmn = min(0, sm);
    }
    if(inv) {
    swap(lmn, lmx); lmn = -lmn; lmx = -lmx;
    swap(rmn, rmx); rmn = -rmn; rmx = -rmx;
    sm = -sm;
    }
    if(rev) {
    swap(lmx, rmx);
    swap(lmn, rmn);
    }
    }
    inline int Query() {
    return (lmx + 1) / 2 + (-rmn + 1) / 2;
    }
    } *Root, pool[maxn], *pt;
     
    void InitSplay() {
    pt = pool;
    Root = Null = pt++;
    Null->Clr();
    Null->setc(Null, 0);
    Null->setc(Null, 1);
    }
     
    Node* NewNode(int v) {
    pt->Clr();
    pt->v = v;
    pt->s = 1;
    pt->p = Null;
    return pt++;
    }
     
    void Rot(Node* t) {
    Node* p = t->p;
    p->pushDown();
    t->pushDown();
    int d = t->d();
    p->p->setc(t, p->d());
    p->setc(t->ch[d ^ 1], d);
    t->setc(p, d ^ 1);
    p->upd();
    if(p == Root)
    Root = t;
    }
     
    Node* Select(int k) {
    for(Node* t = Root; ; ) {
    t->pushDown();
    int s = t->ch[0]->s;
    if(k == s)
    return t;
    if(k > s)
    k -= s + 1, t = t->ch[1];
    else
    t = t->ch[0];
    }
    }
     
    void Splay(Node* t, Node* f = Null) {
    for(Node* p = t->p; p != f; p = t->p) {
    if(p->p != f)
    t->d() != p->d() ? Rot(t) : Rot(p);
    Rot(t);
    }
    t->upd();
    }
     
    Node* Range(int l, int r) {
    Splay(Select(--l));
    Splay(Select(++r), Root);
    return Root->ch[1]->ch[0];
    }
     
    int N;
    char s[maxn];
     
    Node* Build(int l, int r) {
    if(l >= r)
    return Null;
    int m = (l + r) >> 1;
    Node* t = NewNode(s[m] != ')' ? -1 : 1);
    t->setc(Build(l, m), 0);
    t->setc(Build(m + 1, r), 1);
    t->upd();
    return t;
    }
     
    int main() {
    InitSplay();
    int m;
    scanf("%d%d", &N, &m);
    scanf("%s", s + 1);
    Root = Build(0, N + 2);
    while(m--) {
    int l, r;
    scanf("%s%d%d", s, &l, &r);
    Node* t = Range(l, r);
    if(s[0] == 'R') {
    char c;
    scanf(" %c", &c);
    t->Tg(c != '(' ? 1 : -1);
    } else if(s[0] == 'S') {
    t->Rev();
    } else if(s[0] == 'I') {
    t->Inv();
    } else
    printf("%d ", t->Query());
    Splay(t);
    }
    return 0;
    }

    --------------------------------------------------------------------------------

    2329: [HNOI2011]括号修复

    Time Limit: 40 Sec  Memory Limit: 128 MB
    Submit: 798  Solved: 368
    [Submit][Status][Discuss]

    Description

    Input

    Output

    Sample Input

    Sample Output

    HINT

    Source

  • 相关阅读:
    在Mac OS X上配置Apache2
    Safari on iOS 7 中Element.getClientRects的Bug
    Ubuntu 升级到13.10之后出现Apache2启动失败的问题
    HTML5中DOM元素的querySelector/querySelectorAll的工作机制
    TLS之上的HTTP
    Linux常用设置
    http 连接复用
    js数组的操作
    https学习总结
    教你使用shell数组
  • 原文地址:https://www.cnblogs.com/JSZX11556/p/5020634.html
Copyright © 2011-2022 走看看