题意是一条线上的点,D x是破坏这个点,Q x是表示查询以x所在的最长的连续的点的个数,R是恢复上一次破坏的点。
线段树结点 设置一个 ll 记录区间左端点开始的最大连续个数, rl 记录区间右端点开始的最大的连续个数,
ml表示该区间最大的连续点的个数。

主要是更新和查询两个操作。

/*
key: ll,rl,ml;//左起最大长度,右起最大长度,区间最大长度

求与某点相连的连续最长距离。
线段树优化了求连续最长的时间,枚举是O(n),线段树O(log2[n])
*/

#include <cstdio>
#include <stack>
using namespace std;

#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define N 50005

int max3(int x, int y, int z)
{
    x = x > y ? x : y;
    return z > x ? z : x;
}

struct Seq
{
    int ll,rl,ml;//左起最大长度,右起最大长度,区间最大长度
}seq[N<<2];

stack<int> st;

void build(int l, int r, int rt)
{
    if(l==r)
        seq[rt].ml = seq[rt].ll = seq[rt].rl = 1;
    else
    {
        int m = (l + r) >> 1;
        build(lson);
        build(rson);
        seq[rt].ml = seq[rt].ll = seq[rt].rl = seq[rt<<1].ml + seq[rt<<1|1].ml;
    }
}

void update(int i, int add, int l, int r, int rt)
{
    if(l==r)
    {
        seq[rt].ml = add;
        seq[rt].ll = seq[rt].rl = seq[rt].ml;
    }
    else
    {
        int m = (l + r) >> 1;
        if(i<=m)
            update(i, add, lson);
        else
            update(i, add, rson);
        seq[rt].ll = seq[rt<<1].ll;
        if(m-l+1== seq[rt<<1].ml)//左孩子区间最大长度等于区间长度
            seq[rt].ll += seq[rt<<1|1].ll;
        seq[rt].rl = seq[rt<<1|1].rl;
        if(r - m == seq[rt<<1|1].ml)//右孩子区间最大长度等于区间长度
            seq[rt].rl += seq[rt<<1].rl;
        //父亲节点区间最大长度 为 max(左孩子右起最大长度+右孩子左起最大长度 ,左孩子区间最大长度,右孩子区间最大长度)
        seq[rt].ml = max3(seq[rt<<1].ml, seq[rt<<1|1].ml, seq[rt<<1].rl+seq[rt<<1|1].ll);
    }
}

int query(int pos, int l, int r, int rt)
{
    if(l==r || seq[rt].ml==0 || seq[rt].ml == r - l + 1)//叶子节点 或 区间最大长度等0 或 区间最大长度等于整个区间长度
        return seq[rt].ml;
    else
    {
        int m = (l + r) >> 1;
        int ret = 0;
        if(pos<=m)//查找点在左子树
        {
            ret = query(pos, l, m, rt<<1);
            if(pos > m - seq[rt<<1].rl)//查找点在右起第一断点的右边
                ret += seq[rt<<1|1].ll;
        }
        else//在右子树
        {
            ret = query(pos, m+1, r, rt<<1|1);
            if(pos < m + 1 + seq[rt<<1|1].ll)//查找点在左起第一断点的左边
                ret += seq[rt<<1].rl;
        }
        return ret;
    }
}

int main()
{
    int n, m, x;
    char s[5];
    while(scanf("%d%d", &n, &m)!=EOF)
    {
    build(1, n, 1);
    while(!st.empty()) st.pop();
    for(int i=1; i<=m; i++)
    {
        scanf("%s",s);
        if(s[0]=='D')
        {
            scanf("%d",&x);
            update(x, 0, 1, n, 1);
            st.push(x);
        }
        else if(s[0]=='R')
        {
            x = st.top();
            st.pop();
            update(x, 1, 1, n, 1);
        }
        else if(s[0]=='Q')
        {
            scanf("%d",&x);
            printf("%d\n",query(x, 1, n, 1));
        }
    }
    }
    return 0;
}

View Code

转载于:https://www.cnblogs.com/byluoluo/p/3418498.html

hdu 1540 Tunnel Warfare (线段树维护左右最长连续区间)相关推荐

  1. hdu 1540 Tunnel Warfare(线段树区间合并)

    hdu 1540 Tunnel Warfare 记录每个节点的最大左连续值.最大右连续值.最大连续值,向上更新的是常规的区间合并处理方式 关键是想到如何去查询,如果查询节点落在左儿子节点的右连续段中, ...

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

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

  3. HDU - 1540 Tunnel Warfare(线段树+区间合并)

    题目链接:点击查看 题目大意:给定n个村庄,初始化全部连接为一条直线,需要依次执行m个操作,D表示摧毁第i个村庄的连接,R表示恢复最后一 个被摧毁的村庄的连接,Q表示询问包括本身在内,与第i个村庄相连 ...

  4. HDU 1540 Tunnel Warfare

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1540 解题思路:线段树节点增加一个ld----区间左端点起始的最大长度,rd----区间右端点起始的最 ...

  5. HDOJ1540 - Tunnel Warfare 线段树区间合并

    HDOJ 1540 题目大意:给定两个整数N,M, 其中N表示一共有N个村庄,M代表有M次操作,操作有以下: 1.    D x  销毁村庄x 2.    Q x  询问与村庄x相邻的村庄总数 3.  ...

  6. HDU-1540 Tunnel Warfare 线段树最大连续区间 或 STL巧解

    题目大意 n个点,m个操作(1<=n,m<=5e4),m行中每行一个字符c表示操作类型,一个整型数x表示第x个点 D x 表示去掉第x点,Q x表示需输出含 x 的最大连续区间的长度,R ...

  7. 线段树维护(最大区间和,最大子段和,最长连续上升子序列)

    本文主要介绍用线段树来维护(最大区间和,最大子段和,最长连续上升子序列)的问题. HDU 1540 Tunnel Warfare(最长连续区间+单点修改) 洛谷 P2894 [USACO08FEB]酒 ...

  8. HDU 2681 MM Programming Club(miaos的线段树维护+ycy的暴力贪心)

    Description ACM is popular in HDU. Many girls want to learn more about programming skills in ACM. As ...

  9. hdu 2871 Memory Control(线段树)

    题目链接:hdu 2871 Memory Control 题目大意:模拟一个内存分配机制. Reset:重置,释放全部空间 New x:申请内存为x的空间,输出左地址 Free x:释放地址x所在的内 ...

  10. [动态dp]线段树维护转移矩阵

    背景:czy上课讲了新知识,从未见到过,总结一下. 所谓动态dp,是在动态规划的基础上,需要维护一些修改操作的算法. 这类题目分为如下三个步骤:(都是对于常系数齐次递推问题) 1先不考虑修改,不考虑区 ...

最新文章

  1. Openfire3.10beta版源码在eclipse上部署编译
  2. 使用七牛云对网站进行加速基本配置
  3. c语言程序设计 第三版 哈工大,c语言程序设计 哈工大 苏小红 第三章习题
  4. OpenGL入门-2-颜色
  5. 高薪必备|Redis 基础、高级特性与性能调优
  6. MongoDB-与SpringBoot集成
  7. Linux下Shell 备份脚本集合
  8. android百度地图单点定位_Android百度地图实现搜索和定位及自定义图标绘制并点击时弹出泡泡...
  9. Snmp4j编程简介之二:PDU
  10. virtualbox虚拟机迁移
  11. ​有哪些比较好的录制游戏视频软件​,游戏录屏软件哪个好用
  12. 论信贷企业信用评级与债券信用评级的关系
  13. python extractor_Python Extractor for Python Editor 1.2
  14. 值得推荐的经济学中文教材-转
  15. TCP协议拥塞控制算法(Reno、HSTCP、BIC、Vegas、Westwood)
  16. IT行业里的热门技术 | 热门IT技术项目分享 | 详细介绍一下机器人技术
  17. java向MySQL插入当前时间的几种方式
  18. Map 和 ForEach 的区别
  19. 大年初一微信闪退?看看如何修复的 1
  20. ArcGis处理水力梯度,用栅格计算器求水位年际变化等

热门文章

  1. iOS UI08_TableView界面传值
  2. cocos2dx-3.0(8)------Label、LabelTTF、LabelAtlas、LabelBMFont使用之法
  3. android获取Mac地址和IP地址
  4. OpenGL(一)二维图形的绘制:一个简单的绘制矩形程序
  5. TFS Two Build Definations Share the Same Code Branch
  6. 程序员职业发展三阶段
  7. [数据结构] 树链剖分
  8. js高级学习笔记(b站尚硅谷)-4-函数
  9. Vue3中导入项目Eslint和TS语法检测问题解决方案
  10. powerbi python词云图_Power BI 标签云可视化