您的位置:首页 > 其它

HDU 1540 Tunnel Warfare

2013-05-22 09:50 337 查看
线段树点修改+区间合并

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

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>

using namespace std;

#define lc rt << 1
#define rc rt << 1 | 1
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1

const int MAXN = 50002;

int N, Q;
int stack[MAXN];
int top;
int len[ MAXN << 2 ];
int Llen[ MAXN << 2 ];
int Rlen[ MAXN << 2 ];
bool lbd[ MAXN << 2 ];
bool rbd[ MAXN << 2 ];

void PushUp( int rt, int l, int r, int m )
{
len[rt] = max( len[lc], len[rc] );
if ( rbd[lc] && lbd[rc] )
len[rt] = max( len[rt], Llen[rc] + Rlen[lc] );

lbd[rt] = lbd[lc];
rbd[rt] = rbd[rc];

Llen[rt] = Llen[lc];
Rlen[rt] = Rlen[rc];

if ( Llen[lc] == m - l + 1 ) Llen[rt] += Llen[rc];
if ( Rlen[rc] == r - m ) Rlen[rt] += Rlen[lc];

return;
}

void build( int l, int r, int rt )
{
if ( l == r )
{
lbd[rt] = rbd[rt] = true;
len[rt] = 1;
Llen[rt] = Rlen[rt] = 1;
return;
}

int m = ( l + r ) >> 1;
build( lson );
build( rson );
PushUp( rt, l, r, m );
return;
}

void Update( int L, int c, int l, int r, int rt )
{
if ( L == l && L == r )
{
len[rt] = Llen[rt] = Rlen[rt] = c;
if ( c == 1 ) lbd[rt] = rbd[rt] = true;
else lbd[rt] = rbd[rt] = false;
return;
}

int m = ( l + r ) >> 1;
if ( L <= m ) Update( L, c, lson );
else Update( L, c, rson );
PushUp( rt, l, r, m );

return;
}

int Query( int L, int l, int r, int rt )
{
if ( l == r || !len[rt] || len[rt] == r - l + 1 ) return len[rt];
int m = ( l + r ) >> 1;
if ( L <= m )
{
if ( L > m - Rlen[lc] ) return Query( L, lson ) + Query( m + 1, rson );
else return Query( L, lson );
}
else
{
if ( L < m + 1 + Llen[rc] ) return Query( m, lson ) + Query( L, rson );
else return Query( L, rson );
}
}

int main()
{
//freopen( "in.txt", "r", stdin );
//freopen( "out.txt", "w", stdout );
while ( ~scanf( "%d%d", &N, &Q ) )
{
build( 1, N, 1 );
top = 0;
while ( Q-- )
{
char str[4];
scanf( "%s", str );
if ( str[0] == 'R' )
{
if ( top > 0 )
Update( stack[top--], 1, 1, N, 1 );
}
else
{
int a;
scanf( "%d", &a );
if ( str[0] == 'D' )
{
Update( a, 0, 1, N, 1 );
stack[ ++top ] = a;
}
else
printf( "%d\n", Query( a, 1, N, 1 ) );
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: