Tunnel Warfare HDU

来源:互联网 发布:nginx 转发到其他ip 编辑:程序博客网 时间:2024/05/22 14:11

题目链接http://acm.hdu.edu.cn/showproblem.php?pid=1540


思路:

1.注意一下恢复的情况,村庄可以被破坏多次,只需要一次就可以恢复

2.最大连续区间  注释很详细了

#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>using namespace std; const int N = 5e4+10; struct node{int l,r;int ms,ls,rs; // ls是左区间的长度,rs是右区间长度,ms是区间里面的最大长度 int mid() {  return (l+r)/2; }};node num[N*4]; void build( int root,int l,int r ) {num[root].l = l ; num[root].r = r; num[root].ms = num[root].ls = num[root].rs = r-l+1; if ( l==r ) return ; build( root*2,  l,num[root].mid() );build( root*2+1, num[root].mid()+1 , r );return ; }void update( int root,int pos,int op ) {if ( num[root].l==num[root].r ) {num[root].ls = num[root].rs = num[root].ms = op ; return ;}if ( pos<=num[root].mid() ) update( root*2,pos,op ); else update( root*2+1,pos,op ) ; num[root].ls = num[root*2].ls; //root左区间 是左子树的左区间的长度 num[root].rs = num[root*2+1].rs;  //root右区间 是右子树的右区间的长度 if ( num[root*2].r-num[root*2].ls+1==num[root*2].l ) num[root].ls += num[root*2+1].ls; //如果左子树的区间长度覆盖整个左子树的长度,它就和右子树的左区间连在了一起,所以加上右子树的左区间 if ( num[root*2+1].r-num[root*2+1].rs+1==num[root*2+1].l ) num[root].rs += num[root*2].rs; num[root].ms = max( max( num[root*2].ms,num[root*2+1].ms) , num[root*2].rs+num[root*2+1].ls ); return ; }int query( int root,int pos ) {//如果区间的最大长度是0   或者  查找到了根节点  或者  区间最大连续长度就是整个区间的长度  就返回 if ( num[root].ms==0 || (num[root].ms==num[root].r-num[root].l+1) || num[root].l==num[root].r )return num[root].ms; if ( pos<=num[root].mid() ) {//如果pos在左子树的右区间里面,那么它的连续长度需要加上右子树的第一个值的连续长度. if ( pos>=num[root*2].r-num[root*2].rs+1 )  return query( root*2,pos ) + query( root*2+1,num[root].mid()+1 ) ; //return query( root*2,pos ) + num[root*2+1].ls ; 和上一句是一模一样的效果 else return query( root*2,pos ); }else {if ( pos <= num[root*2+1].l+num[root*2+1].ls-1 )  return query( root*2+1,pos ) + query( root*2,num[root].mid() ) ;  ///mid-1//return query( root*2+1,pos ) + num[root*2].rs ;  和上一句是一模一样的效果 else return query( root*2+1,pos ); }}int n,q; bool vis[N]; int s[N];int top=0; char c; int main(){int temp,ans; while ( scanf("%d%d",&n,&q)!=EOF ) {memset( vis,false,sizeof(vis) ); top = 0; //!!!!!build( 1,1,n); while ( q-- ) {scanf(" %c",&c);if ( c=='D' ) {scanf("%d",&temp); vis[temp] = 1; s[top++] = temp; update( 1,temp,0 ); }else if ( c=='R' ) {temp = s[--top]; if ( vis[temp] ) {update( 1,temp,1 ) ; vis[temp] = 0; }else temp = s[--top]; }else {scanf("%d",&temp); ans = query( 1,temp ) ; cout<<ans<<endl ;}}} return 0 ; }


0 0
原创粉丝点击