http://acm.hdu.edu.cn/showproblem.php?pid=1540

题目大意:抗日战争期间进行地道战,存在n个村庄用地道连接,输入D表示破坏某个村庄(摧毁与其相连的地道, 包括其本身),输入R表示重建最后被破坏的那个村庄。

输入Q表示查询某村庄可通过地道到达多少个村庄(包含本身)。

将题目理想化,即为找与某点直接或间接相连的有多少个点。即通过此点的线段的最大长度。当此点时破坏时默认为0.抽象为此过程后发现即为在线段上执行的操作,即线

段树知识点。分析:此点可能为孤立(0), 可能位于某线段左区间的线段,可能位于某线段右区间的线段,可能为左右区间都经过的线段。故在线段树种定义lsum表示此

区间左端向右可到达的极限长度,rsum表示此区间从右端向左可达到的极限长度, sum表示此区间内的最大长度。分析更新,注意细节即可。

#include <stdio.h>
#include <stack>
#include <algorithm>
using namespace std;
#define lson rt<<1
#define rson rt<<1|1
#define N 100005
struct tree
{
    int l, r, lsum, rsum, sum;
    int mid()
    {
        return (l+r)/2;
    }
    int len()
    {
        return (r-l+1);
    }
}a[N<<2];
void build(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(lson, l, a[rt].mid());
    build(rson, a[rt].mid()+1, r);
}
void Combine(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[rson].lsum;
    if(a[rson].rsum == a[rson].len())
        a[rt].rsum += a[lson].rsum;

a[rt].sum = max(max(a[rt].lsum, a[rt].rsum), a[lson].rsum+a[rson].lsum);
}
void Destroy(int rt, int k, int e)
{
    if(a[rt].l==a[rt].r)
    {
        a[rt].lsum = a[rt].rsum = a[rt].sum = e;
        return ;
    }
    if(a[rt].mid()>=k)Destroy(lson, k, e);
    else Destroy(rson, k, e);

Combine(rt);
}
int Query(int rt, int k)
{
    if(a[rt].sum == 0)return 0;///在点上
    if(k<a[rt].l+a[rt].lsum)return a[rt].lsum;///在线段中;
    if(k>a[rt].r-a[rt].rsum)return a[rt].rsum;
    if(k>a[lson].r-a[lson].rsum && k<a[rson].lsum+a[rson].l)
        return a[lson].rsum + a[rson].lsum;

if(a[rt].mid()>=k)return Query(lson, k);
    else return Query(rson, k);
}
int main()
{
    int m, n;
    while(scanf("%d %d", &n, &m)!=EOF)
    {
        build(1, 1, n);
        char order[10];
        int x;
        stack<int>Q;
        while(m--)
        {
            scanf("%s", order);
            if(order[0]=='D')
            {
                scanf("%d", &x);
                Q.push(x);
                Destroy(1, x, 0);
            }
            else if(order[0]=='R' && Q.size())
            {
                x = Q.top();
                Q.pop();
                Destroy(1, x, 1);
            }
            else
            {
                scanf("%d", &x);
                printf("%d\n", Query(1, x));
            }
        }
    }
    return 0;
}

HDU 1540 Tunnel Warfare(线段树+区间合并)的更多相关文章

  1. HDU 1540 Tunnel Warfare 线段树区间合并

    Tunnel Warfare 题意:D代表破坏村庄,R代表修复最后被破坏的那个村庄,Q代表询问包括x在内的最大连续区间是多少 思路:一个节点的最大连续区间由(左儿子的最大的连续区间,右儿子的最大连续区 ...

  2. hdu 1540 Tunnel Warfare 线段树 区间合并

    题意: 三个操作符 D x:摧毁第x个隧道 R x:修复上一个被摧毁的隧道,将摧毁的隧道入栈,修复就出栈 Q x:查询x所在的最长未摧毁隧道的区间长度. 1.如果当前区间全是未摧毁隧道,返回长度 2. ...

  3. hdu 1540 Tunnel Warfare(线段树区间统计)

    Tunnel Warfare Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) T ...

  4. hdu 1540 Tunnel Warfare 线段树 单点更新,查询区间长度,区间合并

    Tunnel Warfare Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pi ...

  5. Tunnel Warfare 线段树 区间合并|最大最小值

    B - Tunnel WarfareHDU - 1540 这个有两种方法,一个是区间和并,这个我个人感觉异常恶心 第二种方法就是找最大最小值 kuangbin——线段树专题 H - Tunnel Wa ...

  6. HDU 1540 Tunnel Warfare (线段树)

    Tunnel Warfare Problem Description During the War of Resistance Against Japan, tunnel warfare was ca ...

  7. HDU 1540 Tunnel Warfare (线段树)

    题目大意: n 个村庄排列在一条直线上,相邻的村庄有地道连接,除首尾两个村庄外,其余村庄都有两个相邻的村庄.其中有 3 中操作 D x :表示摧毁编号为 x 的村庄,Q x:表示求出包含村庄 x 的最 ...

  8. HDU 1540 Tunnel Warfare (线段树或set水过)

    题意:D代表破坏村庄,R代表修复最后被破坏的那个村庄,Q代表询问包括x在内的最大连续区间是多少. 析:首先可以用set水过,set用来记录每个被破坏的村庄,然后查找时,只要查找左右两个端点好. 用线段 ...

  9. HDU1540 Tunnel Warfare —— 线段树 区间合并

    题目链接:https://vjudge.net/problem/HDU-1540 uring the War of Resistance Against Japan, tunnel warfare w ...

  10. HDU 6638 - Snowy Smile 线段树区间合并+暴力枚举

    HDU 6638 - Snowy Smile 题意 给你\(n\)个点的坐标\((x,\ y)\)和对应的权值\(w\),让你找到一个矩形,使这个矩阵里面点的权值总和最大. 思路 先离散化纵坐标\(y ...

随机推荐

  1. SQL2005 : 如何在SQL Server Profiler (事件查看器)中 跟踪查看死锁恢复

    SQL Profiler 通过 SQL Profiler 工具程序,可监控应用程序如何访问数据库引擎.普通来说,当系统性能需要优化或是应用程序对数据库访问的结果不合预期,都可以使用该工具确认视图问题所 ...

  2. python学习-day15:函数作用域、匿名函数、函数式编程、map、filter、reduce函数、内置函数r

    ---恢复内容开始--- 一.全局变量与局部变量 在子程序中定义的变量称为局部变量, 在程序的一开始定义的变量称为全局变量. 全局变量作用域是整个程序,局部变量作用域是定义该变量的子程序.当全局变量与 ...

  3. 极限编程之TDD

         测试驱动开发(Test-Driven Development,TDD)是通过测试定义所要开发的功能的接口,然后实现功能的开发过程. Test-Driven Development(TDD), ...

  4. yum install nginx

    先安装nginx的yum源 http://nginx.org/en/linux_packages.html#stable 找到链接,安装: rpm -ivh http://nginx.org/pack ...

  5. Codeforces 723d [暴力dfs]

    /* 不要低头,不要放弃,不要气馁,不要慌张. 题意: 给n,m和k,n和m为所给矩阵的高和宽.k是要求最多剩下的湖的数量. 在所给的矩阵中,*代表陆地,.代表水. 湖的定义是一片连续的水(上下左右四 ...

  6. Android UI 绘制过程浅析(二)onMeasure过程

    前言 View的绘制过程分为 measure.layout.draw三个步骤,接下来对这三个步骤逐一进行研究. measure方法的签名 public final void measure(int w ...

  7. PHP的命名空间

    简介: 防止名称冲突. 原理: 类似文件目录/usr/local这样的. 用法: namespace:定义命名空间: use:取别名: 代码示例:file 1.php <?php namespa ...

  8. Linux ToolChain (二) --- Linker (1)链接选项 -L -rpath -rpath-link

    一.动态库的链接和链接选项-L,-rpath-link,-rpath (1). 现代连接器在处理动态库时将链接时路径(Link-time path)和运行时路径(Run-time path)分开, 用 ...

  9. php把错误日志输入到文件里。

    display_errors = On 开启状态下,若出现错误,则报错,出现错误提示 dispaly_errors = Off 关闭状态下,若出现错误,则提示:服务器错误.但是不会出现错误提示 log ...

  10. transition实现自定义tips淡入淡出效果

    transition实现动画的时候,只能实现指定属性的渐变,元素显隐要通过opacity来实现: 做了一个小的demo: <!doctype html> <html> < ...