hdu1540 线段树(区间合并)

题意:有n个村庄,m个事件。村庄一开始是从小到大连续的,有三种操作

(1)D a为摧毁第a个村庄。

(2)Q a为询问与第a个村子直接和间接相连的村子有多少个。

(3)R 为恢复最近销毁的那个村庄

思路:难得想的是询问操作,恢复操作用一个栈保存就可以了。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <stack>
using namespace  std;
#define maxn 100009
#define lson left,mid,rt<<1
#define rson mid+1,right,rt<<1|1

struct node
{
    int lmx, rmx;
} sum[maxn << 2];

void push_up(int rt, int left, int right)
{
    sum[rt].lmx = sum[rt << 1].lmx;
    sum[rt].rmx = sum[rt << 1 | 1].rmx;
    int mid = (left + right) >> 1;
    if(sum[rt << 1].lmx == mid - left + 1)
        sum[rt].lmx += sum[rt << 1 | 1].lmx;
    if(sum[rt << 1 | 1].rmx == right - mid)
        sum[rt].rmx += sum[rt << 1].rmx;
}
void build(int left, int right, int rt)
{
    if(left == right)
    {
        sum[rt].lmx = sum[rt].rmx = 1;
        return ;
    }
    int mid = (left + right) >> 1;
    build(lson);
    build(rson);
    push_up(rt, left, right);
}
void update(int pos, int val, int left, int right, int rt)
{

    if(left == right)
    {
        if(val == -1)
            sum[rt].lmx = sum[rt].rmx = 0;
        if(val == 1)
            sum[rt].lmx = sum[rt].rmx = 1;
        return ;
    }
    int mid = (left + right) >> 1;
    if(pos <= mid) update(pos, val, lson);
    else   update(pos, val, rson);
    push_up(rt, left, right);
}
void  query(int pos, int &s, int &e, int left, int right, int rt)
{
    if(left == right)
    {
        if(sum[rt].lmx == 1) s = e = left;
        else s = e = 0;
        return ;
    }
    int mid = (left + right) >> 1;
    if(pos <= mid) query(pos, s, e, lson);
    else query(pos, s, e, rson);
    if(mid == e) e += sum[rt << 1 | 1].lmx;
    if(mid == s) s -= sum[rt << 1].rmx;

}
int main()
{
    int n, m;
    int a;
    while(scanf("%d%d", &n, &m) != EOF)
    {
        stack<int>st;
        build(1, n, 1);
        while(m--)
        {
            int s, e;
            char c[5];
            scanf("%s", c);
            if(c[0] == 'D')
            {
                scanf("%d", &a);
                update(a, -1, 1, n, 1);
                st.push(a);
            }
            else if(c[0] == 'Q')
            {
                scanf("%d", &a);
                query(a, s, e, 1, n, 1);
                printf("%d\n", e - s);
            }
            else
            {
                a = st.top();
                st.pop();
                update(a, 1, 1, n, 1);
            }
        }
    }
    return 0;
}
View Code

 

 

posted on 2013-12-08 20:42  黎昊明  阅读(155)  评论(0编辑  收藏  举报

导航