博客
关于我
P2894 [USACO08FEB]Hotel G (线段树)
阅读量:803 次
发布时间:2019-03-25

本文共 1961 字,大约阅读时间需要 6 分钟。

线段树的建筑与更新过程就像一座站在_MONITOR_转台上看不见的城市,所有细节都隐藏在代码之下。让我告诉你,这个结构是如何工作的。

首先,线段树的核心是每个节点,它们保存着相关的信息:

  • ans:记录当前区间内最长的连续空房数。
  • pans:记录从区间左端开始的最长连续空房数。
  • sans:记录从区间右端开始的最长连续空房数。

这三个值在每个节点中都有对应的字段,确保在合并子节点时能够准确反映整个父节点的状态。

为了便于解释,我会从组建线段树开始,直到操作更新和查询的过程。

文件结构

包括以下内容:

#include 
using namespace std;#define ll long longconst int maxn = 5e5 + 7;const ll inf = 34359738370;

自定义了一个线段树:

struct node {    int ans;    int pans, sans;} tree[maxn << 2];int tag[maxn << 2];int n, m;

辅助函数:

inline int lc(int rt) {    return rt << 1;}inline int rc(int rt) {    return rt << 1 | 1;}inline void pushup(int rt, int l, int r) {    int mid = (l + r) >> 1;    int m = tree[lc(rt)].sans + tree[rc(rt)].pans;    tree[rt].ans = max(max(tree[lc(rt)].ans, tree[rc(rt)].ans), m);}

组建线段树

构建函数:

inline void build(int rt, int l, int r) {    if(l == r) {        tree[rt].ans = 1;        return;    }    int mid = (l + r) >> 1;    build(lc(rt), l, mid);    build(rc(rt), mid+1, r);    pushup(rt, l, r);}

更新操作

更新函数:

inline void updata(int rt, int l, int r, int vl, int vr, int v) {    if(r < vl || l > vr) return;    if(vl <= l && r <= vr) {        if(v == 0) {            tree[rt].ans = tree[rt].pans = tree[rt].sans = 0;            tag[rt] = 1;        } else {            tree[rt].ans = tree[rt].pans = tree[rt].sans = r - l + 1;            tag[rt] = 2;        }        return;    }    pushdown(rt, l, r);    int mid = (l + r) >> 1;    updata(lc(rt), l, mid, vl, vr, v);    updata(rc(rt), mid+1, r, vl, vr, v);    pushup(rt, l, r);}

查询操作

查询函数:

inline int query(int rt, int l, int r, int x) {    pushdown(rt, l, r);    if(l == r) return l;    int mid = (l + r) >> 1;    if(tree[lc(rt)].ans >= x) {        return query(lc(rt), l, mid, x);    }    if(tree[lc(rt)].sans + tree[rc(rt)].pans >= x) {        return mid + 1 - tree[lc(rt)].sans;    }    return query(rc(rt), mid+1, r, x);}

线段树通过递归分割区间,管理各层处理任务。使用时,可以通过更新和查询方法,实现对特定区间的操作。节点标记和分裂功能确保数据在合并和分割时准确传递信息。

理论上,这个线段树可以处理多种区间操作,适用于需要快速、高效处理区间问题的场景。

转载地址:http://ykjyk.baihongyu.com/

你可能感兴趣的文章
Python中pip安装模块太慢
查看>>
docker安装
查看>>
N皇后问题解法(递归+回朔)
查看>>
面试题 08.01. 三步问题
查看>>
剑指 Offer 11. 旋转数组的最小数字
查看>>
剑指 Offer 57. 和为s的两个数字
查看>>
git 在本地删除、添加远端的源
查看>>
字符串的反转
查看>>
word文档注入(追踪word文档)未完
查看>>
作为我的第一篇csdn博客吧
查看>>
java中简单实现栈
查看>>
ajax异步提交失败
查看>>
打开cmd,输入java,java -version没有问题,但是javac提示不是内部命令?
查看>>
一道简单的访问越界、栈溢出pwn解题记录
查看>>
ubuntu18.04.4版本安装docker教程
查看>>
VsCode配置c运行环境
查看>>
Stream 某些API
查看>>
关于项目中 对Java 的为空判断整理
查看>>
测试调用另一台电脑ip是否有用
查看>>
mos-excel集成文档
查看>>