• 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
    ", e - s);
                }
                else
                {
                    a = st.top();
                    st.pop();
                    update(a, 1, 1, n, 1);
                }
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    在线考试————随机出题
    HTTP协议
    团队
    做作业
    图书馆管理说明书性能
    关于敏捷开发的学习
    运行环境
    图书馆管理系统说明书
    性能(2)
    作业
  • 原文地址:https://www.cnblogs.com/BruceNoOne/p/3464228.html
Copyright © 2020-2023  润新知