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

线段树-模板-区间查询-区间修改

【模板】线段树 2

传送门:https://www.luogu.com.cn/problem/P3373
题单:https://www.luogu.com.cn/training/16376#problems

题目描述

如题,已知一个数列,你需要进行下面三种操作:

  • 将某区间每一个数乘上 x x x
  • 将某区间每一个数加上 x x x
  • 求出某区间每一个数的和。

输入格式

第一行包含三个整数 n , q , m n,q,m n,q,m,分别表示该数列数字的个数、操作的总个数和模数。

第二行包含 n n n 个用空格分隔的整数,其中第 i i i 个数字表示数列第 i i i 项的初始值。

接下来 q q q 行每行包含若干个整数,表示一个操作,具体如下:

操作 1 1 1: 格式:1 x y k 含义:将区间 [ x , y ] [x,y] [x,y] 内每个数乘上 k k k

操作 2 2 2: 格式:2 x y k 含义:将区间 [ x , y ] [x,y] [x,y] 内每个数加上 k k k

操作 3 3 3: 格式:3 x y 含义:输出区间 [ x , y ] [x,y] [x,y] 内每个数的和对 m m m 取模所得的结果

输出格式

输出包含若干行整数,即为所有操作 3 3 3 的结果。

样例 #1

样例输入 #1

5 5 38
1 5 4 2 3
2 1 4 1
3 2 5
1 2 4 2
2 3 5 5
3 1 4

样例输出 #1

17
2

提示

【数据范围】

对于 30 % 30\% 30% 的数据: n ≤ 8 n \le 8 n8 q ≤ 10 q \le 10 q10
对于 70 % 70\% 70% 的数据:$n \le 10^3 , , q \le 10^4$。
对于 100 % 100\% 100% 的数据: 1 ≤ n ≤ 1 0 5 1 \le n \le 10^5 1n105 1 ≤ q ≤ 1 0 5 1 \le q \le 10^5 1q105

除样例外, m = 571373 m = 571373 m=571373

(数据已经过加强 _

样例说明:

故输出应为 17 17 17 2 2 2 40 m o d 38 = 2 40 \bmod 38 = 2 40mod38=2)。

代码

#include <bits/stdc++.h>#define MAXN 100010
#define ll long longusing namespace std;int n, m, mod;
int a[MAXN];struct Segment_Tree {ll sum, add, mul;int l, r;
}s[MAXN * 4];void update(int pos) {s[pos].sum = (s[pos << 1].sum + s[pos << 1 | 1].sum) % mod;return;
}void pushdown(int pos) { //pushdown的维护s[pos << 1].sum = (s[pos << 1].sum * s[pos].mul + s[pos].add * (s[pos << 1].r - s[pos << 1].l + 1)) % mod;s[pos << 1 | 1].sum = (s[pos << 1 | 1].sum * s[pos].mul + s[pos].add * (s[pos << 1 | 1].r - s[pos << 1 | 1].l + 1)) % mod;s[pos << 1].mul = (s[pos << 1].mul * s[pos].mul) % mod;s[pos << 1 | 1].mul = (s[pos << 1 | 1].mul * s[pos].mul) % mod;s[pos << 1].add = (s[pos << 1].add * s[pos].mul + s[pos].add) % mod;s[pos << 1 | 1].add = (s[pos << 1 | 1].add * s[pos].mul + s[pos].add) % mod;s[pos].add = 0;s[pos].mul = 1;return; 
}void build_tree(int pos, int l, int r) { //建树s[pos].l = l;s[pos].r = r;s[pos].mul = 1;if (l == r) {s[pos].sum = a[l] % mod;return;}int mid = (l + r) >> 1;build_tree(pos << 1, l, mid);build_tree(pos << 1 | 1, mid + 1, r);update(pos);return;
}void ChangeMul(int pos, int x, int y, int k) { //区间乘法if (x <= s[pos].l && s[pos].r <= y) {s[pos].add = (s[pos].add * k) % mod;s[pos].mul = (s[pos].mul * k) % mod;s[pos].sum = (s[pos].sum * k) % mod;return;}pushdown(pos);int mid = (s[pos].l + s[pos].r) >> 1;if (x <= mid) ChangeMul(pos << 1, x, y, k);if (y > mid) ChangeMul(pos << 1 | 1, x, y, k);update(pos);return;
}void ChangeAdd(int pos, int x, int y, int k) { //区间加法if (x <= s[pos].l && s[pos].r <= y) {s[pos].add = (s[pos].add + k) % mod;s[pos].sum = (s[pos].sum + k * (s[pos].r - s[pos].l + 1)) % mod;return;}pushdown(pos);int mid = (s[pos].l + s[pos].r) >> 1;if (x <= mid) ChangeAdd(pos << 1, x, y, k);if (y > mid) ChangeAdd(pos << 1 | 1, x, y, k);update(pos);return;
}ll AskRange(int pos, int x, int y) { //区间询问if (x <= s[pos].l && s[pos].r <= y) {return s[pos].sum;}pushdown(pos);ll val = 0;int mid = (s[pos].l + s[pos].r) >> 1;if (x <= mid) val = (val + AskRange(pos << 1, x, y)) % mod;if (y > mid) val = (val + AskRange(pos << 1 | 1, x, y)) % mod;return val;
}int main() {scanf("%d%d%d", &n, &m, &mod);for (int i = 1; i <= n; i++) {scanf("%d", &a[i]);}build_tree(1, 1, n);for (int i = 1; i <= m; i++) {int opt, x, y;scanf("%d%d%d", &opt, &x, &y);if (opt == 1) {int k;scanf("%d", &k);ChangeMul(1, x, y, k);}if (opt == 2) {int k;scanf("%d", &k);ChangeAdd(1, x, y, k);}if (opt == 3) {printf("%lld\n", AskRange(1, x, y));}}return 0;
}
http://www.lryc.cn/news/123365.html

相关文章:

  • 微服务架构和分布式架构的区别
  • Ajax-概念、Http协议、Ajax请求及其常见问题
  • react 09之状态管理工具1 redux+ react-thunk的使用实现跨组件状态管理与异步操作
  • opencv实战项目 手势识别-实现尺寸缩放效果
  • Netty对HPACK头部压缩的支持
  • C++:替换string中的字符
  • 【ChatGPT】自我救赎
  • 微信小程序(由浅到深)
  • 冒泡排序 简单选择排序 插入排序 快速排序
  • linux文件I/O之 open() 函数用法
  • 用Java操作MySQL数据库
  • SpringBoot启动报错:java: 无法访问org.springframework.boot.SpringApplication
  • Vue3 setup语法糖 解决富文本编辑器上传图片64位码过长问题 quill-image-extend-module
  • 百度坐标(BD09)、国测局坐标(火星坐标,GCJ02)、和WGS84坐标系之间的转换
  • 论文浅尝 | CI4MRC:基于因果推断去除机器阅读理解中的名字偏差
  • 【校招VIP】测试计划之黑盒测试白盒测试
  • 学习笔记整理-JS-01-语法与变量
  • PHP之PHPExcel
  • Redis系列(一):深入了解Redis数据类型和底层数据结构
  • javaScript:如何获取html中的元素对象
  • 面试总结-webpack/git
  • 深入解析美颜SDK:算法、效果与实现
  • ChatGPT Plus和ChatGPT对比
  • 计算机网络 运输层 TCP连接建立、释放
  • npm run xxx 的时候发生了什么?(以npm run dev举例说明)
  • 图解结构体大小和位域例子
  • 游戏行业实战案例 5 :玩家在线分布
  • TypeScript 关于对【泛型】的定义使用解读
  • 盛元广通食品药品检验检测实验室LIMS系统
  • 【数据结构】-- 栈和队列