您的位置:首页 > 其它

HDU-1540 Tunnel Warfare 线段树 区间合并

2013-10-17 18:20 423 查看
http://acm.hdu.edu.cn/showproblem.php?pid=1540

题意:

给出直线上一系列的村庄,如果相邻村庄都没有被破坏,

则两村庄是连接的,题目给出一系列的破坏操作,对指定号码的村庄进行破坏,

还有一系列的询问操作,询问与指定号码的村庄直接相连或间接相连的村庄有几个,

还有一个修复操作,是对最后破坏的村庄进行修复。

//线段树

定义三个变量:lmax[rt] 表示从左孩子开始的连续区间个数

rmax[rt] 到右孩子截至的连续区间个数

mmax[rt] 整个区间连续的区间个数

col[rt] 表示区间的状态,0表示未必破坏,1表示已被破坏,-1初始状态

因为为连续区间关键步骤是pushdown 里的赋值操作和pushup的更新操作

#include "stdio.h"
#include "string.h"
const int maxn = 50005;
int n,q,x,val;
int stack[maxn],top;
bool vis[maxn];
struct node
{
int col;              //表示区间的状态,0表示未必破坏,1表示已被破坏,-1初始状态
int rmax,lmax,mmax;   //到右孩子截至的连续区间个数  表示从左孩子开始的连续区间个数 整个区间连续的区间个数
}tree[maxn*4];
int Max( int a,int b )
{
return a>=b?a:b;
}
void pushup( int ld,int rd,int t )
{
int mid = ( ld+rd )>>1;
tree[t].lmax = tree[t<<1].lmax;
tree[t].rmax = tree[t<<1|1].rmax;
tree[t].mmax = Max( tree[t<<1].mmax,tree[t<<1|1].mmax );

if( tree[t<<1].lmax == mid - ld +1 )
{
tree[t].lmax += tree[t<<1|1].lmax;
}
if( tree[t<<1|1].rmax == rd - mid )
{
tree[t].rmax += tree[t<<1].rmax;
}
tree[t].mmax = Max( tree[t].mmax,tree[t<<1].rmax+tree[t<<1|1].lmax);
}

void pushdown( int ld,int rd,int t )
{
if( tree[t].col!=-1 )
{
int mid = ( ld+rd )>>1;
tree[t<<1].col = tree[t<<1|1].col =tree[t].col;
if( tree[t].col==1 )
{
tree[t<<1].lmax = tree[t<<1].rmax = tree[t<<1].mmax = 0;
tree[t<<1|1].lmax = tree[t<<1|1].rmax = tree[t<<1|1].mmax = 0;
}
else
{
tree[t<<1].lmax = tree[t<<1].rmax = tree[t<<1].mmax = mid-ld+1;
tree[t<<1|1].lmax = tree[t<<1|1].rmax = tree[t<<1|1].mmax = rd-mid;
}
tree[t].col = -1;
}
}

void buildtree( int ld,int rd,int t )
{
tree[t].col = -1;
tree[t].rmax = tree[t].lmax = tree[t].mmax = rd-ld+1;
if( ld == rd )
return;
int mid = ( ld+rd )>>1;
buildtree( ld,mid,t<<1 );
buildtree( mid+1,rd,t<<1|1 );
}

void updata( int ld,int rd,int t )
{
if( ld == rd )
{
tree[t].col = val;
tree[t].lmax = tree[t].rmax = tree[t].mmax = ( val?0:1 );
return;
}
pushdown( ld,rd,t );
int mid = ( ld+rd )>>1;
if( x<=mid )
updata( ld,mid,t<<1 );
else
updata( mid+1,rd,t<<1|1 );
pushup( ld,rd,t );
}

int query( int ld,int rd,int t )
{
if( ld == rd || tree[t].mmax==( rd-ld+1 ) || !tree[t].mmax )
{
return tree[t].mmax;
}
int mid = ( ld+rd )>>1;
if( x<=mid )
{
if( x >= mid - tree[t<<1].rmax+1 )
return tree[t<<1].rmax + tree[t<<1|1].lmax;
else
return query( ld,mid,t<<1 );
}
else
{
if( x <= mid + tree[t<<1|1].lmax+1 )
return tree[t<<1].rmax + tree[t<<1|1].lmax;
else
return query( mid+1,rd,t<<1|1 );
}
}

int main()
{
int i;
char ch[3];
while( scanf("%d%d",&n,&q)==2 )
{
top = 0;
memset(vis,0,sizeof(vis));
getchar();
buildtree( 1,n,1 );
for( i=1;i<=q;i++ )
{
scanf("%s",ch);
if( ch[0]=='D' )
{
scanf("%d",&x);
stack[++top] = x;
val = 1;//1为摧毁
if( !vis[x] )
updata(1,n,1);
vis[x] = 1;
}
else if( ch[0]=='Q' )
{
scanf("%d",&x);
printf("%d\n",vis[x]?0:query(1,n,1) );
}
else
{
if( top )
{
x = stack[top--];
val = 0;//0为修复
if( vis[x] )
updata( 1,n,1 );
vis[x] = 0;
}
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: