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\n", 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

 

posted @ 2015-06-13 12:30  idy002  阅读(213)  评论(0编辑  收藏  举报