hdu 1540 Tunnel Warfare

 

时隔一年做了这道历史悠久的题目,之前不知道是什么原因写到一半不写了,这次再看这道题,有了些思路,其实并不难,只是要把那些条件分开,不可混淆。

线段树区间合并,主要是进行合并。

/*
题意:D代表破坏村庄,
R代表修复最后被破坏的那个村庄,
Q代表询问包括x在内的最大连续区间是多少
*/
#include <iostream>
#include <cstdio>
#include <stack>
#include <cstring>

using namespace std;

const int maxn=50005;
#define lson rt<<1
#define rson rt<<1|1

struct st
{
    int l,r;
    int lsum, rsum, sum;
    int mid()
    {
        return (l+r)>>1;
    }
    int len()
    {
        return (r-l+1);
    }
}a[maxn<<2];

void Build_Tree(int rt,int l,int r)
{
    a[rt].l = l;
    a[rt].r = r;
    a[rt].lsum = a[rt].rsum = a[rt].sum = a[rt].len();
    if(l==r)
    {
        return ;
    }
    Build_Tree(lson, l, a[rt].mid());
    Build_Tree(rson, a[rt].mid()+1, r);
}

void pushdown(int rt)//进行合并
{
    a[rt].lsum = a[lson].lsum;
    a[rt].rsum = a[rson].rsum;
    if(a[lson].lsum==a[lson].len())
        a[rt].lsum = a[lson].lsum+a[rson].lsum;
    if(a[rson].lsum==a[rson].len())
        a[rt].rsum = a[lson].rsum+a[rson].lsum;

    a[rt].sum = max(a[rt].rsum, a[rt].lsum);
    a[rt].sum = max(a[rt].sum, a[lson].rsum+a[rson].lsum);
}

void change(int rt, int index, int x)
{
    if(a[rt].l == index && a[rt].r == index)
    {
        a[rt].sum = a[rt].lsum = a[rt].rsum = x;
        return ;
    }
    if(index<=a[rt].mid())
        change(lson, index, x);
    else
        change(rson, index, x);
    pushdown(rt);
}

int Query(int rt, int index)
{
    if(a[rt].sum==0)//找到一点
        return 0;
    if(index<a[rt].l+a[rt].lsum)//左端区间上
        return a[rt].lsum;
    if(index>a[rt].r-a[rt].rsum)//右端区间上
        return a[rt].rsum;
    if(index>a[lson].r-a[lson].rsum && index<a[rson].l+a[rson].lsum)//中间
        return a[lson].rsum+a[rson].lsum;

    if(index<=a[rt].mid())
        return Query(lson, index);
    else
        return Query(rson, index);
}

int main()
{
    int m, n;
    char str[10];
    stack<int> sta;
    while(~scanf("%d%d",&n,&m))
    {
        while(!sta.empty())
            sta.pop();
        Build_Tree(1,1,n);
        int x;
        for(int i=1;i<=m;i++)
        {
            scanf("%s",str);

            if(str[0] == 'D')
            {
                scanf("%d", &x);
                sta.push(x);
                change(1, x, 0);
            }
            else if(str[0] == 'Q')
            {
                scanf("%d", &x);
                int ans = Query(1, x);
                printf("%d\n", ans);
            }
            else if(!sta.empty())
            {
                x = sta.top();
                sta.pop();
                change(1, x, 1);
            }
        }
    }

    return 0;
}

 

posted @ 2015-08-08 01:04  梦中。。  阅读(176)  评论(0编辑  收藏  举报