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

洛谷 P3373 【模板】线段树 2- 普及+/提高

题目描述

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

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

输入格式

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

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

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

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

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

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

输出格式

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

输入输出样例 #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≤8n \le 8n8q≤10q \le 10q10
对于 70%70\%70% 的数据:$n \le 10^3 ,,q \le 10^4$。
对于 100%100\%100% 的数据:1≤n≤1051 \le n \le 10^51n1051≤q≤105,1≤ai,k≤1041 \le q \le 10^5,1\le a_i,k\le 10^41q105,1ai,k104

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

(数据已经过加强 _

样例说明:

故输出应为 17171722240 mod 38=240 \bmod 38 = 240mod38=2)。

solution

对于乘法操作,sum add mul 都需要乘
对于加法操作,sum mul 都要加

代码

#include <sstream>
#include "iostream"
#include "cmath"
#include "vector"
#include "algorithm"using namespace std;
const int N = 1e5 + 5;int n, mod;
long long b[N];struct node {long long sum, add, mul;
} a[4 * N];// 将父节点的 tag 信息向下分摊
void push_down(int rt, int l, int r) {// 先算乘法、再算加法, 因为乘法影响加法,加法不影响乘法int m = r + l >> 1;a[rt * 2].sum = (a[rt * 2].sum * a[rt].mul + a[rt].add * (m + 1 - l)) % mod;a[rt * 2 + 1].sum = (a[rt * 2 + 1].sum * a[rt].mul + a[rt].add * (r - m)) % mod;a[rt * 2].add = (a[rt * 2].add * a[rt].mul + a[rt].add) % mod;a[rt * 2 + 1].add = (a[rt * 2 + 1].add * a[rt].mul + a[rt].add) % mod;a[rt * 2].mul = (a[rt * 2].mul * a[rt].mul) % mod;a[rt * 2 + 1].mul = (a[rt * 2 + 1].mul * a[rt].mul) % mod;a[rt].add = 0;a[rt].mul = 1;
}void push_up(int rt) {a[rt].sum = (a[rt * 2].sum + a[rt * 2 + 1].sum) % mod;
}void build(int rt, int l, int r) {a[rt].add = 0, a[rt].mul = 1;if (l == r) {a[rt].sum = b[l];return;}int m = l + r >> 1;build(rt * 2, l, m);build(rt * 2 + 1, m + 1, r);push_up(rt);
}void update_mul(int rt, int l, int r, int L, int R, int mul) { // l, r 是 rt管理的区间, L R是修改的区间, k 是修改的量// 整个区间都要改变if (L <= l && r <= R) {a[rt].sum = (a[rt].sum * mul) % mod;a[rt].add = (a[rt].add * mul) % mod;a[rt].mul = (a[rt].mul * mul) % mod;return;}push_down(rt, l, r); // tag 向下传递int m = l + r >> 1;if (L <= m) update_mul(rt * 2, l, m, L, R, mul);if (R > m) update_mul(rt * 2 + 1, m + 1, r, L, R, mul);push_up(rt); // sum 向上汇总
}void update_add(int rt, int l, int r, int L, int R, int add) { // l, r 是 rt管理的区间, L R是修改的区间, k 是修改的量// 整个区间都要改变if (L <= l && r <= R) {a[rt].sum = (a[rt].sum + (r - l + 1) * add) % mod;a[rt].add = (a[rt].add + add) % mod;return;}push_down(rt, l, r); // tag 向下传递int m = l + r >> 1;if (L <= m) update_add(rt * 2, l, m, L, R, add);if (R > m) update_add(rt * 2 + 1, m + 1, r, L, R, add);push_up(rt); // sum 向上汇总
}long long query(int rt, int l, int r, int L, int R) {// 整个区间都要if (L <= l && r <= R) {return a[rt].sum;}push_down(rt, l, r);int m = l + r >> 1;long long s = 0;if (L <= m) s += query(rt * 2, l, m, L, R);if (R > m) s += query(rt * 2 + 1, m + 1, r, L, R);return s % mod;
}int main() {int m;cin >> n >> m >> mod;for (int i = 1; i <= n; i++) cin >> b[i];build(1, 1, n);for (int i = 0; i < m; i++) {int op, l, r, k;cin >> op >> l >> r;if (op == 1) {cin >> k;update_mul(1, 1, n, l, r, k);} else if (op == 2) {cin >> k;update_add(1, 1, n, l, r, k);} else {cout << query(1, 1, n, l, r) << endl;}}
}

结果

在这里插入图片描述

http://www.lryc.cn/news/610116.html

相关文章:

  • 《Python 实用项目与工具制作指南》· 3.1 实战·开发题目数据生成器
  • 思科 UCS Fabric Interconnect 和 UCS Manager 简介
  • 比起登天,孙宇晨更需要安稳着陆
  • C语言编程中常用的预定义宏
  • 浅谈 Python 中的 next() 函数 —— 迭代器的驱动引擎
  • 【深度学习新浪潮】近三年城市级数字孪生的研究进展一览
  • push/pop字节对齐使用场景
  • Next Terminal 实战:内网无密码安全登录
  • cocos2 场景跳转传参
  • 佰力博检测与您探讨介温谱和介电谱的区别?
  • 【实战】Dify从0到100进阶--中药科普助手(1)
  • 7.1、《软件工程》-软件生命周期-CMM-开发模型
  • 【2025/08/04】GitHub 今日热门项目
  • 【2025-08-04 Java学习小记】
  • Linux磁盘分区与挂载完全指南
  • Java基础学习(一):类名规范、返回值、注释、数据类型
  • 使用1panel将http升级至https的过程
  • javacc学习笔记 03、编译原理实践 - JavaCC解析表达式并生成抽象语法树
  • 深入解析线程同步中WaitForSingleObject的超时问题
  • 【Java基础知识 17】面向对象编程
  • Adobe Experience Manager (AEM) Assets|企业级数字资产管理平台(DAM)
  • javacc学习笔记 01、JavaCC本地安装与测试
  • TorchDynamo源码解析:从字节码拦截到性能优化的设计与实践
  • 厄米系统(Hermitian System)
  • Go 函数选项模式
  • 模型学习系列之考试
  • day15 SPI
  • 疏老师-python训练营-Day35模型可视化推理
  • Golang中的`io.Copy()`使用场景
  • #C语言——刷题攻略:牛客编程入门训练(四):运算(二)