# bzoj 1095 括号序列求两点距离

建立出树的括号序列,类似这样: [A[B][C]],所以长度为3*n

假如我们要询问AC间的距离,提取出中间的括号:[]],匹配消去后得到],其长度就是距离.

现在我们要做的就是修改点的状态,并且动态维护答案.要用到一些求与绝对值相关的式子的技巧.

  1 /**************************************************************
2     Problem: 1095
3     User: idy002
4     Language: C++
5     Result: Accepted
6     Time:2176 ms
7     Memory:55548 kb
8 ****************************************************************/
9
10 #include <cstdio>
11 #define min(a,b) ((a)<(b)?(a):(b))
12 #define max(a,b) ((a)>(b)?(a):(b))
13 #define N 100010
14 #define M N<<1
15 #define oo 0x3f3f3f3f
16 #define fprintf(...)
17
18 struct Node {
19     int v[7], c, e, a;
20     int lf, rg;
21     Node *ls, *rs;
22     void init( int type ) {
23         if( type==0 ) {
24             a = 0;
25             e = false;
26             c = 1;
27             for( int t=0; t<7; t++ ) v[t]=0;
28         } else if( type==-1 ) { //  (1,0)
29             a = -1;
30             e = true;
31             c = 0;
32             v[1] = v[3] = v[6] = v[2] = v[5] = 1;
33             v[0] = v[4] = -1;
34         } else {                //  (0,1)
35             a = -1;
36             e = true;
37             c = 0;
38             v[1] = v[3] = v[6] = v[0] = v[4] = 1;
39             v[2] = v[5] = -1;
40         }
41     }
42     void update() {
43         e = ls->e && rs->e;
44         v[5] = ls->v[5] + rs->v[5];
45         v[4] = ls->v[4] + rs->v[4];
46         v[6] = max( ls->v[6]+rs->v[4], ls->v[5]+rs->v[6] );
47         if( !ls->e && !rs->e ) {
48             v[0] = max( ls->v[0], ls->v[4]+rs->v[0] );
49             v[1] = max( ls->v[1], max( ls->v[6]+rs->v[0], ls->v[5]+rs->v[1] ) );
50             v[2] = max( rs->v[2], ls->v[2]+rs->v[5] );
51             v[3] = max( rs->v[3], max( ls->v[3]+rs->v[4], ls->v[2]+rs->v[6] ) );
52             a = max( max(ls->v[3]+rs->v[0],ls->v[2]+rs->v[1]), max(ls->a,rs->a) );
53         } else if( !ls->e ) {
54             v[0] = ls->v[0];
55             v[1] = ls->v[1];
56             v[2] = ls->v[2]+rs->v[5];
57             v[3] = max( ls->v[3]+rs->v[4], ls->v[2]+rs->v[6] );
58             a = ls->a;
59         } else if( !rs->e ) {
60             v[0] = ls->v[4]+rs->v[0];
61             v[1] = max( ls->v[6]+rs->v[0], ls->v[5]+rs->v[1] );
62             v[2] = rs->v[2];
63             v[3] = rs->v[3];
64             a = rs->a;
65         } else {
66             a = -1;
67         }
68     }
69     void reverse( int pos ) {
70         if( lf==rg ) {
71             if( c ) {
72                 c = 0;
73                 a = -1;
74                 e = true;
75             } else {
76                 c = 1;
77                 a = 0;
78                 e = false;
79             }
80             return;
81         }
82         int mid=(lf+rg)>>1;
83         if( pos<=mid ) ls->reverse(pos);
84         else rs->reverse(pos);
85         update();
86     }
87 }pool[N*3*3], *tail=pool, *root;
88
89 int n, m;
90 int head[N], dest[M], next[M], etot;
91 int dfn[N], sgn[N*3], fat[N], idc;
92
93 void adde( int u, int v ) {
94     etot++;
96     dest[etot] = v;
98 }
99 void dfs( int u ) {
100     sgn[++idc] = 1;
101     dfn[u] = ++idc;
102     fprintf( stderr, "[" );
103     fprintf( stderr, "%d", u );
104     for( int t=head[u]; t; t=next[t] ) {
105         int v=dest[t];
106         if( v==fat[u] ) continue;
107         fat[v] = u;
108         dfs(v);
109     }
110     sgn[++idc] = -1;
111     fprintf( stderr, "]" );
112 }
113 Node *build( int lf, int rg ) {
114     Node *nd = ++tail;
115     nd->lf=lf, nd->rg=rg;
116     if( lf==rg ) {
117         nd->init( sgn[lf] );
118     } else {
119         int mid=(lf+rg)>>1;
120         nd->ls = build( lf, mid );
121         nd->rs = build( mid+1, rg );
122         nd->update();
123     }
124     fprintf( stderr, "[%d,%d] a=%2d e=%d v[0~6] = %2d %2d %2d %2d %2d %2d %2d\n",
125             lf, rg, nd->a, nd->e, nd->v[0], nd->v[1],
126             nd->v[2], nd->v[3], nd->v[4], nd->v[5], nd->v[6] );
127     return nd;
128 }
129 int main() {
130     scanf( "%d", &n );
131     for( int i=1,u,v; i<n; i++ ) {
132         scanf( "%d%d", &u, &v );
135     }
136     for( int i=1; i<=n+n+n; i++ )
137         fprintf( stderr, "%d", i%10 );
138     fprintf( stderr, "\n" );
139     fat[1] = 0;
140     dfs(1);
141     fprintf( stderr, "\n" );
142     root = build( 1, idc );
143     scanf( "%d", &m );
144     for( int i=1,u; i<=m; i++ ) {
145         char ch[10];
146         scanf( "%s\n", ch );
147         if( ch[0]=='G' ) {
148             printf( "%d\n", root->a );
149         } else {
150             scanf( "%d", &u );
151             root->reverse(dfn[u]);
152         }
153     }
154 }
View Code

posted @ 2015-06-15 20:28  idy002  阅读(381)  评论(0编辑  收藏  举报