I - Tunnel Warfare - hdu 1540(区间合并更新)

题意:在抗日战争期间,地道战在华北平原得到广泛的实施,一般而言,村庄通过一些隧道在一条线上连接,除了两端剩下的每个村庄都有两个相连。
侵略者会频繁的对这些村庄进行扫荡,并且摧他们的地道,当然八路军会把这一些已经被摧毁的村庄修复的,会优先修复最近被破坏的村庄。
分析:被这道题折磨了一上午啊,不过也学到了很多,尤其是这种涉及左右区间的。
*********************************************************************
#include<stdio.h>
#include<algorithm>
#include<stack>
using  namespace std;

const  int maxn =  50005;

struct node
{ // sum代表区间种最大的连续区间,lsum代表左端能到达的最右端的个数
     int L, R, sum, lsum, rsum;
     int Mid(){ return (L+R)/ 2;}
     int Len(){ return (R-L+ 1);}
}a[maxn* 4];

void Up( int r)
{
    a[r].lsum = a[r<< 1].lsum, a[r].rsum = a[r<< 1| 1].rsum;

     if(a[r<< 1].lsum == a[r<< 1].Len())
        a[r].lsum = a[r<< 1].lsum + a[r<< 1| 1].lsum;
     if(a[r<< 1| 1].rsum == a[r<< 1| 1].Len())
        a[r].rsum = a[r<< 1| 1].rsum + a[r<< 1].rsum;

    a[r].sum = max(a[r].lsum, max(a[r].rsum, a[r<< 1].rsum+a[r<< 1| 1].lsum));
}
void Build( int r,  int L,  int R)
{
    a[r].L = L, a[r].R = R;
    a[r].lsum = a[r].rsum = a[r].sum = a[r].Len();

     if(L == R) return ;

    Build(r<< 1, L, a[r].Mid());
    Build(r<< 1| 1, a[r].Mid()+ 1, R);
}
void Insert( int r,  int k,  int e)
{
     if( a[r].L == a[r].R )
    {
        a[r].lsum = a[r].rsum = a[r].sum = e;
         return ;
    }

     if(k <= a[r].Mid())
        Insert(r<< 1, k, e);
     else
        Insert(r<< 1| 1, k, e);

    Up(r);
}
int  Query( int r,  int k)
{
     if(a[r].sum ==  0) return  0;
     if(k < a[r].L+a[r].lsum) return a[r].lsum; // 判断是否在左边
     if(k > a[r].R-a[r].rsum) return a[r].rsum; // 判断是否在右边
     if(k > a[r<< 1].R-a[r<< 1].rsum && k < a[r<< 1| 1].L+a[r<< 1| 1].lsum) // 判断是否在中间
         return a[r<< 1].rsum + a[r<< 1| 1].lsum;

     if(k <= a[r].Mid())
         return Query(r<< 1, k);
     else
         return Query(r<< 1| 1, k);
}

int main()
{
     int N, M;

     while(scanf( " %d%d ", &N, &M) != EOF)
    {
         int x;  char s[ 10];
        stack< int> sta;

        Build( 11, N);

         while(M--)
        {
            scanf( " %s ", s);

             if(s[ 0] ==  ' D ')
            {
                scanf( " %d ", &x);
                Insert( 1, x,  0);
                sta.push(x);
            }
             else  if(s[ 0] ==  ' R ' && sta.size())
            {
                Insert( 1, sta.top(),  1);
                sta.pop();
            }
             else  if(s[ 0] ==  ' Q ')
            {
                scanf( " %d ", &x);
                printf( " %d\n ", Query( 1, x));
            }
        }
    }

     return  0;  

}

 

你可能感兴趣的:(HDU)