HDU 1540 Tunnel Warfare

线段树求一个点所处区间的最大连续长度,用lsum记录区间的左连续长度,rsum记录区间的

右连续长度,查询时判断p点处于左子树还是右子树,然后计算左子树的右连续长度+右子树

的左连续长度的和。

#include<stdio.h>

#include<string.h>

#include<stdlib.h>

#include<algorithm>

using namespace std;

#define lson l, mid, rt << 1

#define rson mid + 1, r, rt << 1 | 1



const int MAXN = 50050;

int lsum[MAXN << 2], rsum[MAXN << 2];

int stack[MAXN];

int n, m;



void build(int l, int r, int rt)

{

    int mid = l + r >> 1;

    lsum[rt] = rsum[rt] = r - l + 1;

    if(l == r) return;

    build(lson);

    build(rson);

}



void PushUp(int l, int r, int rt)

{

    int mid = l + r >> 1;

    lsum[rt] = lsum[rt << 1];

    rsum[rt] = rsum[rt << 1 | 1];

    if(lsum[rt << 1] == mid - l + 1)

        lsum[rt] += lsum[rt << 1 | 1];

    if(rsum[rt << 1 | 1] == r - mid)

        rsum[rt] += rsum[rt << 1];

}



void update(int c, int p, int l, int r, int rt)

{

    int mid = l + r >> 1;

    if(p <= l && r <= p)

    {

        lsum[rt] = rsum[rt] = c;

        return;

    }

    if(p <= mid)

        update(c, p, lson);

    else

        update(c, p, rson);

    PushUp(l, r, rt);

}



int query(int p, int l, int r, int rt)

{

    int mid = l + r >> 1;

    if(p <= l && r <= p)

    {

        return lsum[rt];

    }

    if(p <= mid)

    {

        if(mid - rsum[rt << 1] + 1 <= p) //判断p所处的位置

        {

            return rsum[rt << 1] + lsum[rt << 1 | 1];

        }

        else

            return query(p, lson);

    }

    else

    {

        if(mid + 1 + lsum[rt << 1 | 1] - 1 >= p)

        {

            return rsum[rt << 1] + lsum[rt << 1 | 1];

        }

        else

            return query(p, rson);

    }

}



void operation()

{

    int top = 0, x;

    char op[5];

    while(m --)

    {

        scanf("%s", op);

        if('D' == op[0])

        {

            scanf("%d", &x);

            stack[++ top] = x;

            update(0, x, 1, n, 1);

        }

        else if('Q' == op[0])

        {

            scanf("%d", &x);

            printf("%d\n", query(x, 1, n, 1));

        }

        else

        {

            x = stack[top --];

            update(1, x, 1, n, 1);

        }

    }

}



int main()

{



    while(scanf("%d%d", &n, &m) == 2)

    {

        build(1, n, 1);

        operation();

    }

    return 0;

}

 

 

你可能感兴趣的:(HDU)