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

厦门网站建设找维品wordpress多菜单

厦门网站建设找维品,wordpress多菜单,西安国内做网站的公司有哪些,农商网站建设个人总结洛谷P3373题目概述 洛谷P3373是一道关于线段树的模板题,题目名称为“【模板】线段树 2”。题目的主要要求是对一个长度为 n 的数列进行如下操作: 将某区间每个数乘上一个数。将某区间每个数加上一个数。求出某区间所有数的和。 线段树简介 线段树是一…

洛谷P3373题目概述

洛谷P3373是一道关于线段树的模板题,题目名称为“【模板】线段树 2”。题目的主要要求是对一个长度为 n 的数列进行如下操作:

  1. 将某区间每个数乘上一个数。
  2. 将某区间每个数加上一个数。
  3. 求出某区间所有数的和。

线段树简介

线段树是一种二叉树数据结构,常用于高效处理区间查询和更新操作。它可以将一个区间划分为多个子区间,每个节点代表一个区间,通过维护这些节点的信息,可以在 O ( log ⁡ n ) O(\log n) O(logn) 的时间复杂度内完成区间查询和更新操作。

代码详细讲解

1. 头文件和宏定义
#include <iostream>
#include <cmath>
using namespace std;
#define MAXN 400002
#define lson (root*2)
#define rson (root*2+1)
  • #include <iostream>#include <cmath> 分别引入输入输出流和数学库。
  • using namespace std; 表示使用标准命名空间。
  • MAXN 定义了线段树数组的最大长度,通常为 4 n 4n 4n,因为线段树的节点数最多为 4 n 4n 4n
  • lsonrson 分别表示当前节点的左子节点和右子节点的编号。
2. 全局变量
int MOD;
long long sgmt[MAXN], lazy_mul[MAXN], lazy_add[MAXN];
  • MOD 是取模的基数,用于防止结果溢出。
  • sgmt[MAXN] 是线段树数组,用于存储每个节点所代表区间的和。
  • lazy_mul[MAXN]lazy_add[MAXN] 是懒标记数组,分别用于标记乘法和加法操作。
3. push_up 函数
void push_up(int root) {sgmt[root] = sgmt[lson] + sgmt[rson];sgmt[root] %= MOD;
}
  • 该函数用于将左右子节点的信息更新到父节点。具体来说,将左子节点和右子节点所代表区间的和相加,并取模后赋值给父节点。
4. push_down 函数
void push_down(int root, int len) {if (lazy_mul[root] == 1 && lazy_add[root] == 0) return;lazy_mul[lson] *= lazy_mul[root], lazy_mul[lson] %= MOD;lazy_mul[rson] *= lazy_mul[root], lazy_mul[rson] %= MOD;lazy_add[lson] *= lazy_mul[root], lazy_add[lson] %= MOD;lazy_add[rson] *= lazy_mul[root], lazy_add[rson] %= MOD;lazy_add[lson] += lazy_add[root], lazy_add[lson] %= MOD;lazy_add[rson] += lazy_add[root], lazy_add[rson] %= MOD;sgmt[lson] *= lazy_mul[root], sgmt[lson] %= MOD;sgmt[lson] += (len/2)*lazy_add[root], sgmt[lson] %= MOD;sgmt[rson] *= lazy_mul[root], sgmt[rson] %= MOD;sgmt[rson] += (len/2)*lazy_add[root], sgmt[rson] %= MOD;lazy_mul[root] = 1, lazy_add[root] = 0;
}
  • 该函数用于将当前节点的懒标记下推到左右子节点。
  • 首先判断当前节点是否有懒标记,如果 lazy_mul[root] 为 1 且 lazy_add[root] 为 0,则说明没有懒标记,直接返回。
  • 然后将当前节点的乘法懒标记和加法懒标记下推到左右子节点,并更新左右子节点的线段树数组和懒标记数组。
  • 最后将当前节点的懒标记重置为初始值。
5. update 函数
void update(int a, int b, long long c, long long d, int l, int r, int root) {if (a <= l && r <= b) {sgmt[root] *= c, sgmt[root] %= MOD;sgmt[root] += (r-l+1)*d, sgmt[root] %= MOD;lazy_mul[root] *= c, lazy_mul[root] %= MOD;lazy_add[root] *= c, lazy_add[root] %= MOD;lazy_add[root] += d, lazy_add[root] %= MOD;return;}push_down(root,r-l+1);int mid = (l+r)/2;if (a <= mid) update(a,b,c,d,l,mid,lson);if (b > mid) update(a,b,c,d,mid+1,r,rson);push_up(root);
}
  • 该函数用于更新区间 [a, b] 内的所有数,将每个数先乘上 c,再加上 d
  • 如果当前节点所代表的区间完全包含在 [a, b] 内,则直接更新当前节点的线段树数组和懒标记数组。
  • 否则,先将当前节点的懒标记下推,然后递归更新左右子节点,最后更新当前节点的线段树数组。
6. query 函数
long long query(int a, int b, int l, int r, int root) {if (a <= l && r <= b) return sgmt[root];push_down(root,r-l+1);long long ans = 0;int mid = (l+r)/2;if (a <= mid) ans += query(a,b,l,mid,lson), ans %= MOD;if (b > mid) ans += query(a,b,mid+1,r,rson), ans %= MOD;return ans;
}
  • 该函数用于查询区间 [a, b] 内所有数的和。
  • 如果当前节点所代表的区间完全包含在 [a, b] 内,则直接返回当前节点的线段树数组的值。
  • 否则,先将当前节点的懒标记下推,然后递归查询左右子节点,并将结果相加。
7. build 函数
void build(int l, int r, int root) {if (l == r) return;int mid = (l+r)/2;build(l,mid,lson);build(mid+1,r,rson);push_up(root);return;
}
  • 该函数用于构建线段树。
  • 如果当前节点所代表的区间只有一个元素,则直接返回。
  • 否则,递归构建左右子节点,然后更新当前节点的线段树数组。
8. main 函数
int main() {for (int i = 1; i < MAXN; i++)lazy_mul[i] = 1;int n, m; cin >> n >> m >> MOD;int npot = 1 << (int)ceil(log2(n));for (int i = 0; i < n; i++)cin >> sgmt[npot+i];n = npot;int l = 1, r = n, root = 1;build(l,r,root);while (m--) {int op, a, b, c; cin >> op >> a >> b;if (op == 1) {cin >> c; update(a,b,c,0,l,r,root);} else if (op == 2) {cin >> c; update(a,b,1,c,l,r,root);} elsecout << query(a,b,l,r,root)%MOD << endl;}return 0;
}
  • 首先将所有乘法懒标记初始化为 1。
  • 然后读取数列的长度 n、操作的次数 m 和取模的基数 MOD
  • 接着将数列存储在线段树数组中,并将 n 扩展为 2 的幂次方。
  • 调用 build 函数构建线段树。
  • 最后循环处理 m 次操作,根据操作类型调用 updatequery 函数。

复杂度分析

  • 时间复杂度:每次更新和查询操作的时间复杂度均为 O ( log ⁡ n ) O(\log n) O(logn),因此总的时间复杂度为 O ( m log ⁡ n ) O(m \log n) O(mlogn)
  • 空间复杂度:线段树数组和懒标记数组的空间复杂度均为 O ( 4 n ) O(4n) O(4n),因此总的空间复杂度为 O ( n ) O(n) O(n)

完整代码:

// P3373 【模板】线段树 2
#include <iostream>
#include <cmath>
using namespace std;
#define MAXN 400002
#define lson (root*2)
#define rson (root*2+1)int MOD;
long long sgmt[MAXN], lazy_mul[MAXN], lazy_add[MAXN];void push_up(int root) {sgmt[root] = sgmt[lson] + sgmt[rson];sgmt[root] %= MOD;
}void push_down(int root, int len) {if (lazy_mul[root] == 1 && lazy_add == 0) return;lazy_mul[lson] *= lazy_mul[root], lazy_mul[lson] %= MOD;lazy_mul[rson] *= lazy_mul[root], lazy_mul[rson] %= MOD;lazy_add[lson] *= lazy_mul[root], lazy_add[lson] %= MOD;lazy_add[rson] *= lazy_mul[root], lazy_add[rson] %= MOD;lazy_add[lson] += lazy_add[root], lazy_add[lson] %= MOD;lazy_add[rson] += lazy_add[root], lazy_add[rson] %= MOD;sgmt[lson] *= lazy_mul[root], sgmt[lson] %= MOD;sgmt[lson] += (len/2)*lazy_add[root], sgmt[lson] %= MOD;sgmt[rson] *= lazy_mul[root], sgmt[rson] %= MOD;sgmt[rson] += (len/2)*lazy_add[root], sgmt[rson] %= MOD;lazy_mul[root] = 1, lazy_add[root] = 0;
}void update(int a, int b, long long c, long long d, int l, int r, int root) {if (a <= l && r <= b) {sgmt[root] *= c, sgmt[root] %= MOD;sgmt[root] += (r-l+1)*d, sgmt[root] %= MOD;lazy_mul[root] *= c, lazy_mul[root] %= MOD;lazy_add[root] *= c, lazy_add[root] %= MOD;lazy_add[root] += d, lazy_add[root] %= MOD;return;}push_down(root,r-l+1);int mid = (l+r)/2;if (a <= mid) update(a,b,c,d,l,mid,lson);if (b > mid) update(a,b,c,d,mid+1,r,rson);push_up(root);
}long long query(int a, int b, int l, int r, int root) {if (a <= l && r <= b) return sgmt[root];push_down(root,r-l+1);long long ans = 0;int mid = (l+r)/2;if (a <= mid) ans += query(a,b,l,mid,lson), ans %= MOD;if (b > mid) ans += query(a,b,mid+1,r,rson), ans %= MOD;return ans;
}void build(int l, int r, int root) {if (l == r) return;int mid = (l+r)/2;build(l,mid,lson);build(mid+1,r,rson);push_up(root);return;
}int main() {for (int i = 1; i < MAXN; i++)lazy_mul[i] = 1;int n, m; cin >> n >> m >> MOD;int npot = 1 << (int)ceil(log2(n));for (int i = 0; i < n; i++)cin >> sgmt[npot+i];n = npot;int l = 1, r = n, root = 1;build(l,r,root);while (m--) {int op, a, b, c; cin >> op >> a >> b;if (op == 1) {cin >> c; update(a,b,c,0,l,r,root);} else if (op == 2) {cin >> c; update(a,b,1,c,l,r,root);} elsecout << query(a,b,l,r,root)%MOD << endl;}return 0;
}

感谢阅读在这里插入图片描述

http://www.dtcms.com/wzjs/834437.html

相关文章:

  • 模板免费下载网站深圳市设计师服务平台
  • 网站建设 上海珍岛西安市房产信息查询平台官网
  • 莱芜高端网站设计建设可以做h5的软件
  • 免费网站 推广网站邯郸网站制作地方
  • 如何做企业网站wordpress如何导航网站模板
  • 网站设计网址达建网站的需要
  • 类似建设通的网站软件开发工具包下载
  • 织梦做手机网站做搜狗网站优化排名
  • 佛山新网站建设服务河北网络科技公司有哪些
  • 珠海建设网站首页wordpress 站点身份
  • 专门做酒店的网站wordpress登录循环
  • 青岛网站seowordpress 无法登录界面
  • linux 做网站数据库网站有哪些分类
  • 大连企业网站建站网站访问量突然增加
  • 网站需要哪些手续申请免费网站哪个好
  • 做网站一定要买服务器么烟台网站建设九七
  • 模版网站后期可以更换图片吗网站建设费是什么费用
  • 建设个网站广州哪个网站做h5比较好
  • 有那个网站可以做报名链接的网店设计实训报告
  • 网站建设怎么解析域名织梦的手机端网站模板下载
  • 深圳宝安网站设计公司深圳vi设计多少钱
  • 实验室网站建设意义seo标题优化的方法
  • 奇客影院wordpress宁波seo教程网
  • 网站开发书百度云wordpress 表格提交
  • 南阳定制网站制作价格低杭州做网站模板
  • 不良网站进入窗口软件下载7什么网站上做指甲最便宜
  • 环保h5微网站常用ppt模板网站
  • 中国制造网国际站网址公司网站如何更改内容
  • 怎样建立网站有哪些流程网站系统建设招标
  • dw做的网站怎样做成手机版的9免费建网站