当前位置: 首页 > wzjs >正文

2015做导航网站好新湖南app客户端

2015做导航网站好,新湖南app客户端,当当网站建设目标,国外网站建设方案题目描述 有 n 个位置,编号从 1 到 n,初始所有位置的值为 0 。 需要实现以下两种操作,共调用 m 次: 操作 ( 1 l r v ) :将区间 [l, r] 内的每个数增加 v。操作 ( 2 l r ) :返回区间 [l, r] 的累加和。 …

题目描述

有 n 个位置,编号从 1 到 n,初始所有位置的值为 0 。

需要实现以下两种操作,共调用 m 次:

  1. 操作 ( 1 l r v ) :将区间 [l, r] 内的每个数增加 v。
  2. 操作 ( 2 l r ) :返回区间 [l, r] 的累加和。

输入约束

1 ≤ n ≤ 1 0 9 1 \leq n \leq 10^9 1n109
1 ≤ m ≤ 1 0 3 1 \leq m \leq 10^3 1m103

测试链接

https://www.luogu.com.cn/problem/P2781


提示

  • 该题可以帮助学习开点线段树
  • 核心思想是仅在必要时申请空间,避免浪费存储资源。

题解:动态开点线段树


一、题目分析

该题属于 数据结构——动态开点线段树 的应用,涉及 区间修改(加法)与区间求和
由于 ( n ) 的范围高达 ( 10^9 ),无法使用传统数组存储,需要采用动态开点线段树来解决。


二、解题思路

由于 ( n ) 过大,无法直接建立一个大小为 ( n ) 的数组,因此使用 动态开点线段树,即仅在需要时才创建节点,减少空间浪费。

  • 线段树核心操作

    1. add(l, r, v):将区间 ([l, r]) 内的所有数增加 ( v )。
    2. querySum(l, r):查询区间 ([l, r]) 的累加和。
  • 关键技巧

    1. 动态开点:只在访问到某个区间时才创建子节点,避免对所有 ( n ) 个位置预分配存储。
    2. 延迟标记(懒惰更新)
      • 对某个区间进行加法操作时,不直接递归更新所有子节点,而是打上标记,等到查询或细分区间时再下传标记,减少操作次数,提高效率。

三、代码实现

#include <bits/stdc++.h>#define ll long long
using namespace std;// 预估节点数:操作次数 * 树高 * 2(控制空间开销)
const int N = 8E4 + 10;  int cur = 1; // 当前使用的节点索引
struct Node {int left, right; // 左右子节点索引int add;         // 延迟标记(懒惰标记)ll sum;          // 区间和
} tree[N];// **延迟更新(lazy propagation)**
void lazyAdd(int p, int l, int r, int v) {tree[p].sum += 1LL * v * (r - l + 1); // 更新区间总和(避免溢出)tree[p].add += v; // 记录懒惰标记
}// **上推更新**(合并子区间信息)
void pushup(int p) {int lp = tree[p].left, rp = tree[p].right;tree[p].sum = tree[lp].sum + tree[rp].sum;
}// **下推懒惰标记**
void pushdown(int p, int l, int r) {if (tree[p].add) { // 只有当 add 不为 0 时才需要下推int mid = (l + r) >> 1;if (tree[p].left == 0) tree[p].left = ++cur;lazyAdd(tree[p].left, l, mid, tree[p].add);if (tree[p].right == 0) tree[p].right = ++cur;lazyAdd(tree[p].right, mid + 1, r, tree[p].add);tree[p].add = 0; // 清除当前节点的懒惰标记}
}// **区间加法(更新)**
void add(int p, int l, int r, int jobl, int jobr, int v) {if (jobl <= l && r <= jobr) { // 完全覆盖,直接更新lazyAdd(p, l, r, v);} else { pushdown(p, l, r); // 先下推懒惰标记int mid = (l + r) >> 1;// 左子区间if (jobl <= mid) {if (tree[p].left == 0) tree[p].left = ++cur;add(tree[p].left, l, mid, jobl, jobr, v);}// 右子区间if (mid < jobr) {if (tree[p].right == 0) tree[p].right = ++cur;add(tree[p].right, mid + 1, r, jobl, jobr, v);}pushup(p); // 更新父节点值}
}// **区间查询(求和)**
ll querySum(int p, int l, int r, int jobl, int jobr) {if (jobl <= l && r <= jobr) { // 完全覆盖,直接返回return tree[p].sum;} else {pushdown(p, l, r); // 先下推懒惰标记int mid = (l + r) >> 1;ll sum = 0;if (jobl <= mid && tree[p].left != 0) { sum += querySum(tree[p].left, l, mid, jobl, jobr);}if (mid < jobr && tree[p].right != 0) { sum += querySum(tree[p].right, mid + 1, r, jobl, jobr);}return sum;}
}int main() {int n, m;cin >> n >> m;for (int i = 0, op, l, r, k; i < m; i++) {cin >> op >> l >> r;if (op == 1) { // 区间增加cin >> k;add(1, 1, n, l, r, k);} else { // 区间求和cout << querySum(1, 1, n, l, r) << endl;}}return 0;
}

四、时间 & 空间复杂度分析

时间复杂度

  • add(l, r, v)(区间更新)

    • 最坏情况下,树高为 ( O(log n) )。
    • 由于动态开点,仅访问实际需要的节点,因此时间复杂度接近 ( O(log n) )
  • querySum(l, r)(区间查询)

    • 同样最多访问 ( O(log n) ) 个节点。
    • 时间复杂度 ( O(log n) )
  • 整体复杂度

    • 单次操作:( O(log n) )
    • 总共 ( m ) 次操作:( O(m log n) )

空间复杂度

  • 数组方式:如果直接用数组存储,需要 ( O(n) ) 的空间,但 ( n ) 过大无法接受。
  • 动态开点方式
    • 仅在需要时申请空间。
    • 最坏情况:如果操作覆盖整个 ( n ),最多会创建 ( O(m log n) ) 个节点。
    • 实际情况:一般远小于 ( n )。
    • 空间复杂度:( O(m log n) )

五、总结

  1. 为什么需要动态开点?

    • ( n ) 太大,无法直接用数组存储数据。
    • 通过按需分配节点,减少空间浪费。
  2. 如何优化区间更新?

    • 懒惰标记(Lazy Propagation) 避免不必要的递归更新,提高效率。
  3. 适用场景

    • 适用于 稀疏修改,即数据范围大但实际操作区域较少的情况。
    • 适用于 区间修改 & 区间查询 结合的问题。

本题重点在于 动态开点线段树 + 懒惰标记优化,是处理超大范围数据的关键技巧!


文章转载自:

http://PSzKlvso.csdgt.cn
http://aMNzviRk.csdgt.cn
http://IJXKdPnZ.csdgt.cn
http://41sBk62r.csdgt.cn
http://4C4kchKK.csdgt.cn
http://cjkyYOaM.csdgt.cn
http://qWqbdnAX.csdgt.cn
http://IDdJoKgq.csdgt.cn
http://HTa4Ao1y.csdgt.cn
http://QzGwOg9g.csdgt.cn
http://MkppVfTd.csdgt.cn
http://fyfhzink.csdgt.cn
http://NXoL8hJv.csdgt.cn
http://G1Pgtb5n.csdgt.cn
http://KOOoBs98.csdgt.cn
http://Z63717mv.csdgt.cn
http://8eZsUzIY.csdgt.cn
http://blBdarOM.csdgt.cn
http://Y0Ndo4ak.csdgt.cn
http://VVdip2uQ.csdgt.cn
http://d4kigLOg.csdgt.cn
http://HepIlORg.csdgt.cn
http://kRGMCwLJ.csdgt.cn
http://GHuIcwLO.csdgt.cn
http://eAUVh36U.csdgt.cn
http://TlVqyzMy.csdgt.cn
http://NutLeSDM.csdgt.cn
http://tMPWbCyp.csdgt.cn
http://TrcHUIvB.csdgt.cn
http://eBOGYz3K.csdgt.cn
http://www.dtcms.com/wzjs/614546.html

相关文章:

  • 海尔网站建设的目标是什么免费国产linux服务器系统
  • 怎么做有趣的短视频网站代理公司注册协议书
  • 湘潭网站建设优化建站邱启良 深圳网站建设
  • 怎么建设淘宝联盟的网站网页小游戏在线玩儿
  • 西安做网站比较好的公司网站开发软件启动
  • 网站搬家内页打不开东莞工程网站建设
  • 如何自己做购物网站公司网站用什么语言开发
  • 杭州做产地证去哪个网站wordpress菜单 自定义大小写
  • o2o型网站深圳网站域名
  • 男女做爰视频免费网站商派商城网站建设方案
  • 建设工程施工合同范本哪个网站长沙建网站一般要多少钱
  • 网站建设项目验收付款山西建设注册中心网站
  • 网站开发背景知识品牌建设成绩
  • 常州网站建设套餐免费推广平台有哪些软件
  • 那些网站可以做信息推广摄影 wordpress
  • 建一个营销网站的步骤中国住房和城乡建设部
  • 公司网站能自己做么制作灯笼的手工做法简单漂亮
  • 电子商务网站建设前期规划方案网络营销方案的制定
  • 网站首页跳出弹窗学校网站班级网页建设制度
  • 网站留言板制作单机网页制作工具
  • 河北省住房和城乡建设厅网站微信网站技术方案
  • 图片库网站建设wordpress用户添加资源
  • 网站建设费用属于业务宣传费吗织梦移动端网站怎么做
  • 怎样做网站图清晰大连开发区邮编
  • 网站登录密码怎么取消保存WordPress博客手机主题
  • 用jquery做的网站wordpress 引号 主题 remove_filter
  • 网站开发能干什么男女做的那个视频网站
  • 网站建设 流程网络推广公司利润如何
  • 山东建设和城乡建设厅注册中心网站长春建站塔山双喜
  • 网页模板怎么做网站湖南建设厅网站首页