zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    [转]Native进程的运行过程
    android ARM 汇编学习 —— hello world
    android ARM 汇编学习—— 在 android 设备上编译c/cpp代码并用objdump/readelf等工具分析
    Linux buffer/cache异同
    分布式消息队列RocketMQ与Kafka架构上的巨大差异之1 -- 为什么RocketMQ要去除ZK依赖?
    kafka对比RocketMQ(转)
    Jmeter测试webocket协议
    Linux atop监控工具部署
    MySql计算两个日期的时间差函数
    Python selenium —— 一定要会用selenium的等待,三种等待方式解读(转)
  • 原文地址:https://www.cnblogs.com/BruceNoOne/p/3464228.html
Copyright © 2011-2022 走看看