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. SocketTcpServer

    自定义SocketTcpServer,虽然现在有很多这样的组件,但是有时候还是需要把它集成在你的框架或者产品中,不需要特别强大的功能,根据需求定制.最基本的一个问题是判断数据包的结束,没有像super ...

  2. POJO类中的任何布尔类型的变量,都不要加is

    POJO类中的任何布尔类型的变量,都不要加is,否则部分框架解析会引起序列化错误. 定义为基本数据类型boolean isSuccess:的属性,它的方法也是isSuccess(),HSF框架在反向解 ...

  3. 学习laravel之路由问题 404

    今天配置路由的时候,只有原来的自带路由可用: Route::get('/', function(){    return View::make('hello');}); 再网上搜索了办法:来自:htt ...

  4. 21副GIF动图让你了解各种数学概念

    baidu 21副GIF动图让你了解各种数学概念

  5. MVC:上传文件时限制文件类型

    之前写过一篇:MVC:上传文件 今天补充下一个功能:如何限制上传文件类型 文件类型可以在前段限制,但是太容易被绕过,最好还是在后端处理. 修改upload方法代码: [HttpPost] public ...

  6. 整理QQ数据库sql语句

    设置数据库的时候 qq 号如果用整型,设置成UNSIGNED,不然超过一定数值就错误 UPDATE `sao_qq` SET qq_num = REPLACE ( qq_num, '@qq.com', ...

  7. go1.6.2 linux/amd64 的一个bug: gcc: 无法识别的选项‘-no-pie’

    如果你的linux是中文版的. 即:执行 # echo $LANG 命令,返回的是 zh_CN.UTF-8 则会出现这个bug, 如果是 en_US.UTF-8 则没有这个问题.   这个bug的一个 ...

  8. TFS 2010 如何删除Collection

    在cmd  中 cd 到 目录 c:\Program Files\Microsoft Team Foundation Sever 2010\Tools 执行下面的命令: TfsConfig colle ...

  9. EBS R12重启后无法进入登录页面

    应用启动正常,但无法进入登录页面: The webpage cannot be found HTTP 404 ... No known changes had been made and the Mi ...

  10. PHP获取日期

    <?php echo "今天:".date("Y-m-d")."<br>"; echo "昨天:".d ...