zoukankan      html  css  js  c++  java
  • bzoj 2209 括号序列

    反转操作 + 翻转操作 = 对称操作

    因为上面三个操作都是自己的逆操作,所以我们只需要实现对称操作和反转操作,就可以搞定翻转操作.

      1 #include <cstdio>
      2 #include <algorithm>
      3 #define N 100010
      4 using namespace std;
      5 
      6 struct Node {
      7     int siz, val, clf[2], crg[2], rtag, etag;
      8     Node *ch[2], *par;
      9     void update() {
     10         int v;
     11         v = (ch[0]?ch[0]->crg[0]:0) + val - (ch[1]?ch[1]->clf[0]:0);
     12         clf[0] = (ch[0]?ch[0]->clf[0]:0), crg[0] = (ch[1]?ch[1]->crg[0]:0);
     13         if( v>0 ) crg[0]+=v;
     14         else clf[0]+=-v;
     15         v = (ch[0]?ch[0]->crg[1]:0) + (-val) - (ch[1]?ch[1]->clf[1]:0);
     16         clf[1] = (ch[0]?ch[0]->clf[1]:0), crg[1] = (ch[1]?ch[1]->crg[1]:0);
     17         if( v>0 ) crg[1]+=v;
     18         else clf[1]+=-v;
     19         siz = (ch[0]?ch[0]->siz:0) + 1 + (ch[1]?ch[1]->siz:0);
     20     }
     21     void pushdown() {
     22         if( rtag ) {
     23             if( ch[0] ) ch[0]->reverse();
     24             if( ch[1] ) ch[1]->reverse();
     25             rtag = 0;
     26         }
     27         if( etag ) {
     28             if( ch[0] ) ch[0]->exchange();
     29             if( ch[1] ) ch[1]->exchange();
     30             etag = 0;
     31         }
     32     }
     33     void reverse() {
     34         swap( ch[0], ch[1] );
     35         swap( clf[0], crg[1] );
     36         swap( clf[1], crg[0] );
     37         rtag ^= 1;
     38     }
     39     void exchange() {
     40         swap( clf[0], clf[1] );
     41         swap( crg[0], crg[1] );
     42         val = -val;
     43         etag ^= 1;
     44     }
     45 }pool[N], *tail=pool, *root;
     46 
     47 int n, m;
     48 char buf[N];
     49 
     50 Node *find( int pos ) {
     51     Node *nd = root;
     52     pos++;
     53     while(1) {
     54         nd->pushdown();
     55         int lz = nd->ch[0]?nd->ch[0]->siz:0;
     56         if( pos<=lz ) {
     57             nd=nd->ch[0];
     58         } else if( pos==lz+1 ){
     59             return nd;
     60         } else {
     61             pos -= lz+1;
     62             nd=nd->ch[1];
     63         }
     64     }
     65 }
     66 void rotate( Node *nd, int d ) {
     67     Node *p = nd->par;
     68     Node *s = nd->ch[!d];
     69     Node *ss = s->ch[d];
     70 
     71     if( !p ) root=s;
     72     else p->ch[ nd==p->ch[1] ] = s;
     73     if( s ) s->ch[d] = nd;
     74     nd->ch[!d] = ss;
     75 
     76     nd->par = s;
     77     s->par = p;
     78     if( ss ) ss->par = nd;
     79 
     80     nd->update();
     81     s->update();
     82 }
     83 void bigpush( Node *nd ) {
     84     if( !nd ) return;
     85     bigpush(nd->par);
     86     nd->par->pushdown();
     87 }
     88 void splay( Node *nd, Node *top=0 ) {
     89     while( nd->par!=top ) {
     90         Node *p = nd->par;
     91         int nl = nd==p->ch[0];
     92         if( p->par==top ) {
     93             rotate( p, nl );
     94         } else {
     95             Node *pp = p->par;
     96             int pl = p==pp->ch[0];
     97             if( nl==pl ) {
     98                 rotate( pp, pl );
     99                 rotate( p, nl );
    100             } else {
    101                 rotate( p, nl );
    102                 rotate( pp, pl );
    103             }
    104         }
    105     }
    106 }
    107 Node *fetch( int lf, int rg ) {
    108     Node *nl = find(lf-1);
    109     Node *nr = find(rg+1);
    110     splay(nl);
    111     splay(nr,nl);
    112     return nr->ch[0];
    113 }
    114 Node *newnode( Node *par, int v ) {
    115     Node *nd = ++tail;
    116     nd->par = par;
    117     nd->ch[0] = nd->ch[1] = 0;
    118     nd->siz = 1;
    119     nd->val = v;
    120     nd->clf[0] = v==-1;
    121     nd->crg[0] = v==1;
    122     nd->clf[1] = -v==-1;
    123     nd->crg[1] = -v==1;
    124     nd->rtag = nd->etag = 0;
    125     return nd;
    126 }
    127 Node *build( Node *par, int lf, int rg ) {
    128     if( lf>rg ) return 0;
    129     int mid=(lf+rg)>>1;
    130     Node *nd = newnode( par, buf[mid]=='('?1:-1 );
    131     nd->ch[0] = build( nd, lf, mid-1 );
    132     nd->ch[1] = build( nd, mid+1, rg );
    133     nd->update();
    134     return nd;
    135 }
    136 int query( int lf, int rg ) {
    137     Node *nd = fetch(lf,rg);
    138     return ((nd->clf[0]+1)>>1)+((nd->crg[0]+1)>>1);
    139 }
    140 
    141 
    142 int main() {
    143     scanf( "%d%d", &n, &m );
    144     scanf( "%s", buf+1 );
    145     buf[0] = '(';
    146     buf[n+1] = ')';
    147     root = build( 0, 0, n+1 );
    148     for( int i=1,o,l,r; i<=m; i++ ) {
    149         scanf( "%d%d%d", &o, &l, &r );
    150         if( o==0 ) {
    151             printf( "%d
    ", query(l,r) );
    152         } else if( o==1 ) {
    153             fetch(l,r)->exchange();
    154         } else {
    155             fetch(l,r)->reverse();
    156         }
    157     }
    158 }
    View Code
  • 相关阅读:
    Explain执行计划
    SQL优化(SQL + 索引)
    SQL(含索引)
    分组聚合 merger
    服务分组 group
    多注册中心 registry
    多协议 protocol
    常用协议 —— webservice://
    常用协议 —— http://
    最强AngularJS资源合集
  • 原文地址:https://www.cnblogs.com/idy002/p/4573311.html
Copyright © 2011-2022 走看看