HDU 1540 Tunnel Warfare

线段树点修改+区间合并

对于如何查询连续某块的端点和长度还不太熟……但是属于经典常见操作。

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <cstdlib>
  4 #include <algorithm>
  5 
  6 using namespace std;
  7 
  8 #define lc rt << 1
  9 #define rc rt << 1 | 1
 10 #define lson l, m, rt << 1
 11 #define rson m + 1, r, rt << 1 | 1
 12 
 13 const int MAXN = 50002;
 14 
 15 int N, Q;
 16 int stack[MAXN];
 17 int top;
 18 int len[ MAXN << 2 ];
 19 int Llen[ MAXN << 2 ];
 20 int Rlen[ MAXN << 2 ];
 21 bool lbd[ MAXN << 2 ];
 22 bool rbd[ MAXN << 2 ];
 23 
 24 void PushUp( int rt, int l, int r, int m )
 25 {
 26     len[rt] = max( len[lc], len[rc] );
 27     if ( rbd[lc] && lbd[rc] )
 28         len[rt] = max( len[rt], Llen[rc] + Rlen[lc] );
 29 
 30     lbd[rt] = lbd[lc];
 31     rbd[rt] = rbd[rc];
 32 
 33     Llen[rt] = Llen[lc];
 34     Rlen[rt] = Rlen[rc];
 35 
 36     if ( Llen[lc] == m - l + 1 ) Llen[rt] += Llen[rc];
 37     if ( Rlen[rc] == r - m ) Rlen[rt] += Rlen[lc];
 38 
 39     return;
 40 }
 41 
 42 void build( int l, int r, int rt )
 43 {
 44     if ( l == r )
 45     {
 46         lbd[rt] = rbd[rt] = true;
 47         len[rt] = 1;
 48         Llen[rt] = Rlen[rt] = 1;
 49         return;
 50     }
 51 
 52     int m = ( l + r ) >> 1;
 53     build( lson );
 54     build( rson );
 55     PushUp( rt, l, r, m );
 56     return;
 57 }
 58 
 59 void Update( int L, int c, int l, int r, int rt )
 60 {
 61     if ( L == l && L == r )
 62     {
 63         len[rt] = Llen[rt] = Rlen[rt] = c;
 64         if ( c == 1 ) lbd[rt] = rbd[rt] = true;
 65         else lbd[rt] = rbd[rt] = false;
 66         return;
 67     }
 68 
 69     int m = ( l + r ) >> 1;
 70     if ( L <= m ) Update( L, c, lson );
 71     else Update( L, c, rson );
 72     PushUp( rt, l, r, m );
 73 
 74     return;
 75 }
 76 
 77 int Query( int L, int l, int r, int rt )
 78 {
 79     if ( l == r || !len[rt] || len[rt] == r - l + 1 ) return len[rt];
 80     int m = ( l + r ) >> 1;
 81     if ( L <= m )
 82     {
 83         if ( L > m - Rlen[lc] ) return Query( L, lson ) + Query( m + 1, rson );
 84         else return Query( L, lson );
 85     }
 86     else
 87     {
 88         if ( L < m + 1 + Llen[rc] ) return Query( m, lson ) + Query( L, rson );
 89         else return Query( L, rson );
 90     }
 91 }
 92 
 93 int main()
 94 {
 95     //freopen( "in.txt", "r", stdin );
 96     //freopen( "out.txt", "w", stdout );
 97     while ( ~scanf( "%d%d", &N, &Q ) )
 98     {
 99         build( 1, N, 1 );
100         top = 0;
101         while ( Q-- )
102         {
103             char str[4];
104             scanf( "%s", str );
105             if ( str[0] == 'R' )
106             {
107                 if ( top > 0 )
108                     Update( stack[top--], 1, 1, N, 1 );
109             }
110             else
111             {
112                 int a;
113                 scanf( "%d", &a );
114                 if ( str[0] == 'D' )
115                 {
116                     Update( a, 0, 1, N, 1 );
117                     stack[ ++top ] = a;
118                 }
119                 else
120                     printf( "%d\n", Query( a, 1, N, 1 ) );
121             }
122         }
123     }
124     return 0;
125 }
原文地址:https://www.cnblogs.com/GBRgbr/p/3092201.html