P3373 【模板】线段树 2
时间:2022-06-20
本文章向大家介绍P3373 【模板】线段树 2,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
乘法优先还是加法优先
①加法优先,即规定好segtree[root*2].value=((segtree[root*2].value+segtree[root].add)*segtree[root].mul)%p,问题是这样的话非常不容易进行更新操作,假如改变一下add的数值,mul也要联动变成奇奇怪怪的分数小数损失精度,我们内心是很拒绝的;
②乘法优先,即规定好segtree[root*2].value=(segtree[root*2].value*segtree[root].mul+segtree[root].add*(本区间长度))%p,这样的话假如改变add的数值就只改变add,改变mul的时候把add也对应的乘一下就可以了,没有精度损失,看起来很不错。
(来自洛谷第一篇分析)
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 100005;
ll mod;
ll a[maxn];
struct Node{
int l,r;
ll pre,add,mul;
}t[4*maxn+5];
void build(int p,int l,int r){
t[p].l = l; t[p].r = r;
if(l==r){
t[p].pre = a[l]; t[p].mul = 1;
return ;
}
t[p].mul = 1;
int mid = l+r>>1;
build(p*2,l,mid);
build(p*2+1,mid+1,r);
t[p].pre = (t[2*p].pre + t[2*p+1].pre)%mod;
}
void spread(int p){
t[2*p].pre = (t[2*p].pre*t[p].mul + t[p].add*(t[2*p].r-t[2*p].l+1))%mod;
t[2*p+1].pre = (t[2*p+1].pre*t[p].mul + t[p].add*(t[2*p+1].r-t[2*p+1].l+1))%mod;
t[2*p].mul = (t[p].mul*t[2*p].mul)%mod;
t[2*p+1].mul = (t[p].mul*t[2*p+1].mul)%mod;
t[2*p].add = (t[2*p].add*t[p].mul+t[p].add)%mod;
t[2*p+1].add = (t[2*p+1].add*t[p].mul+t[p].add)%mod;
t[p].mul = 1;
t[p].add = 0;
}
void change1(int p,int l,int r,ll z){//加法更新
if(l<=t[p].l&&r>=t[p].r){
t[p].pre+=z*(t[p].r-t[p].l+1);t[p].pre%=mod;
t[p].add+=z;t[p].add%=mod;//加法只处理加法
return ;
}
spread(p);
int mid = t[p].l+t[p].r>>1;
if(l<=mid)change1(p*2,l,r,z);
if(r>mid)change1(p*2+1,l,r,z);
t[p].pre = (t[2*p].pre + t[2*p+1].pre)%mod;
}
void change2(int p,int l,int r,ll z){//乘法更新
if(l<=t[p].l&&r>=t[p].r){
t[p].pre=(t[p].pre*z)%mod;
t[p].mul=(t[p].mul*z)%mod;
t[p].add=(t[p].add*z)%mod;//乘法 则加全都乘
return ;
}
spread(p);
int mid = t[p].l + t[p].r>>1;
if(l<=mid)change2(p*2,l,r,z);
if(r>mid)change2(p*2+1,l,r,z);
t[p].pre = (t[2*p].pre+t[2*p+1].pre)%mod;
}
ll query(int p,int l,int r){
if(l<=t[p].l&&r>=t[p].r){
return t[p].pre%mod;
}
spread(p);
ll ans = 0;
int mid = t[p].l + t[p].r>>1;
if(l<=mid)ans+=query(p*2,l,r),ans%=mod;
if(r>mid)ans+=query(p*2+1,l,r),ans%=mod;
return ans;
}
int main()
{
int n, m;
scanf("%d%d%lld", &n, &m, &mod);
for(int i=1; i<=n; i++){
scanf("%lld", &a[i]);
}
build(1, 1, n);
while(m--){
int chk;
scanf("%d", &chk);
int x, y;
ll k;
if(chk==1){
scanf("%d%d%lld", &x, &y, &k);
change2(1,x,y,k);
}
else if(chk==2){
scanf("%d%d%lld", &x, &y, &k);
change1(1,x,y,k);
}
else{
scanf("%d%d", &x, &y);
printf("%lldn", query(1,x,y));
}
}
return 0;
}
- 使用ffpython嵌入和扩展python
- FFLIB之FFLUA——C++嵌入Lua&扩展Lua利器
- Python之匿名函数
- H2Engine游戏服务器设计之属性管理器
- linux epoll 开发指南-【ffrpc源码解析】
- Python之递归函数
- 你不得不会的MarkDown
- 状态机的实现探讨
- Docker入门实战(二)——Docker镜像操作
- 使用强大的 Mockito 来测试你的代码
- java学习手册-CentOS 6.3(x86_32)下安装Oracle 10g R2
- Docker入门实战(三)——用Dockerfile构建镜像
- C++中消息自动派发之二 About IDL解析器
- C++中消息自动派发之三 About JSON Encode
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 百万级类别的分类模型的拆分训练
- 关于Spring定义的preDestroy修饰的方法不执行,有以下两种原因,总有一款适合你
- CSP201912-2-回收站选址题目解析-Java ,
- Spring boot框架快速入门
- SpringBoot 跨域问题:Access to XMLHttpRequest at ‘***‘ from origin ‘***‘ has been blocked by CORS policy
- 火车购票-CSP201609-2-Java
- 从后端开发人员的视角:最浅显的理解 Vue
- Sublime怎么默认显示文件路径
- Git 删除已提交的文件
- Sublime 怎么装SQL语法检测器
- Vue 设置环境变量和模式
- 你真的掌握了Python基本语法了吗?
- Mybatis-Generator 代码生成器的使用
- 提高数据分析工作效率-Sublime如何设置默认打开文件格式
- 使用 freemarker 制作代码生成器