模板题目1:https://www.luogu.org/problemnew/show/P3372

懒惰标记讲解:https://www.cnblogs.com/wushengyang/p/11194456.html

这题目只需要用一个懒惰标记,不用考虑顺序。

AC代码:

#include <stdio.h>
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <cctype>
#include <string>
#include <cstring>
#include <algorithm>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <ctime>
#include <vector>
#include <fstream>
#include <list>
#include <iomanip>
#include <numeric>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;
const int inf = 0x3f3f3f3f;
int dir[][]={{,},{,},{,},{,-},{-,},{-,-},{,-},{-,}};
#define pi acos(-1)
#define me0(s) memset(s,0,sizeof(s))
#define me1(s) memset(s,1,sizeof(s))
#define mef(s) memset(s,-1,sizeof(s))
#define meinf(s) memset(s,inf,sizeof(s))
const int N=;
#define ls rt<<1
#define rs rt<<1|1
ll a[N],sum[N*],lazy[N*];
void push_up(ll rt){
sum[rt]=sum[ls]+sum[rs]; //更新和
}
void push_down(ll m,ll rt){ //m为总区间长度
if(lazy[rt]){ //如果懒惰标记存在
lazy[ls]+=lazy[rt]; //左子树懒惰标记等于其本身加父亲节点的值
lazy[rs]+=lazy[rt];
sum[ls]+=lazy[rt]*(m-(m>>)); //懒惰标记乘个数
sum[rs]+=lazy[rt]*(m>>);
lazy[rt]=;
}
}
void build(ll l,ll r,ll rt){ //建树
lazy[rt]=; //可以建树直接赋值0
if(l==r){
sum[rt]=a[l];
return ;
}
ll m=(l+r)>>;
build(l,m,ls);
build(m+,r,rs);
push_up(rt);
}
void update(ll L,ll R,ll c,ll l,ll r,ll rt){//区间更新[l,r],[L,R]代表总区间
if(l<=L&&r>=R){
lazy[rt]+=c; //更新懒惰标记
sum[rt]+=c*(R-L+); //更新节点存的sum值
return ;
}
push_down(R-L+,rt); //所有的节点都更新一遍lazy标记
ll m=(L+R)>>; //总区间的一半
if(l<=m) update(L,m,c,l,r,ls); //注意这里递归的是总区间为变量
if(r>m) update(m+,R,c,l,r,rs);
push_up(rt);
}
ll query(ll L,ll R,ll l,ll r,ll rt){ //[l,r]区间
if(l<=L&&r>=R) return sum[rt];
push_down(R-L+,rt);
ll m=(L+R)>>; //总区间的一半
ll ans=;
if(l<=m) ans+=query(L,m,l,r,ls); //这个递归的也是总区间变量
if(r>m) ans+=query(m+,R,l,r,rs);
return ans;
}
int main(int argc, char * argv[])
{
std::ios::sync_with_stdio(false);
int n,m;
cin>>n>>m;
for(int i=;i<=n;i++) cin>>a[i];
build(,n,);
while(m--){
ll op,x,y,k;
cin>>op;
if(op==){
cin>>x>>y>>k;
update(,n,k,x,y,);
}
if(op==){
cin>>x>>y;
cout<<query(,n,x,y,)<<endl;
}
}
return ;
}

模板题目2:https://www.luogu.org/problemnew/show/P3373

这道题目由于存在多种区间更改操作,所以懒惰标记之间有关系,比如如果先求加法的话给他加上一个懒惰标记,再做乘法的话以前的懒惰标记加的那一部分也同时需要做一次乘法,这样才能完整。

#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;
const int inf = 0x3f3f3f3f;
int dir[][]={{,},{,},{,},{,-},{-,},{-,-},{,-},{-,}};
#define pi acos(-1)
#define ls rt<<1
#define rs rt<<1|1
#define me0(s) memset(s,0,sizeof(s))
#define me1(s) memset(s,1,sizeof(s))
#define mef(s) memset(s,-1,sizeof(s))
#define meinf(s) memset(s,inf,sizeof(s))
const int N=;
ll mod;
ll a[N],sum[N*],lazya[N*],lazym[N*]; //lazya存的加的数,lazym存乘
void push_up(int rt){
sum[rt]=(sum[ls]+sum[rs])%mod;
}
void push_down(ll m,ll rt){
lazya[ls]=(lazya[rt]+lazya[ls]*lazym[rt])%mod;//乘法的分配率
lazya[rs]=(lazya[rt]+lazya[rs]*lazym[rt])%mod;
lazym[ls]=(lazym[rt]*lazym[ls])%mod; //懒惰标记直接乘
lazym[rs]=(lazym[rt]*lazym[rs])%mod;
sum[ls]=(lazya[rt]*(m-(m>>))+sum[ls]*lazym[rt])%mod;
sum[rs]=(lazya[rt]*(m>>)+sum[rs]*lazym[rt])%mod;
lazya[rt]=;
lazym[rt]=;
}
void build(ll l,ll r,ll rt){
lazym[rt]=; //初始化乘值
if(l==r){
sum[rt]=a[l];
return ;
}
ll m=(l+r)>>;
build(l,m,ls);
build(m+,r,rs);
push_up(rt);
}
void update_a(ll L,ll R,ll c,ll l,ll r,ll rt){//做加法
if(l<=L&&r>=R){
sum[rt]=(sum[rt]+(R-L+)*c)%mod;
lazya[rt]=(c+lazya[rt])%mod;
return ;
}
push_down(R-L+,rt);
ll m=(L+R)>>;
if(l<=m) update_a(L,m,c,l,r,ls);
if(r>m) update_a(m+,R,c,l,r,rs);
push_up(rt);
}
void update_m(ll L,ll R,ll c,ll l,ll r,ll rt){//做乘法
if(l<=L&&r>=R){
sum[rt]=(sum[rt]*c)%mod;
lazya[rt]=(c*lazya[rt])%mod;
lazym[rt]=(c*lazym[rt])%mod;
return ;
}
push_down(R-L+,rt);
ll m=(L+R)>>;
if(l<=m) update_m(L,m,c,l,r,ls);
if(r>m) update_m(m+,R,c,l,r,rs);
push_up(rt);
}
ll query(ll L,ll R,ll l,ll r,ll rt){
if(l<=L&&r>=R){
return sum[rt];
}
push_down(R-L+,rt);
ll m=(L+R)>>;
ll ans=;
if(l<=m) ans=(ans+query(L,m,l,r,ls))%mod;
if(r>m) ans=(ans+query(m+,R,l,r,rs))%mod;
return ans%mod;
}
int main(int argc, char * argv[])
{
std::ios::sync_with_stdio(false);
ll n,m,x,y,k,op;
cin>>n>>m>>mod;
for(int i=;i<=n;i++) cin>>a[i];
build(,n,);
while(m--){
cin>>op;
if(op==){
cin>>x>>y>>k;
update_m(,n,k,x,y,);
}
if(op==){
cin>>x>>y>>k;
update_a(,n,k,x,y,);
}
if(op==){
cin>>x>>y;
cout<<query(,n,x,y,)<<endl;
}
}
return ;
}

线段树区间更新+区间求和模板(数组实现)洛谷p3372,p3373的更多相关文章

  1. POJ.2299 Ultra-QuickSort (线段树 单点更新 区间求和 逆序对 离散化)

    POJ.2299 Ultra-QuickSort (线段树 单点更新 区间求和 逆序对 离散化) 题意分析 前置技能 线段树求逆序对 离散化 线段树求逆序对已经说过了,具体方法请看这里 离散化 有些数 ...

  2. POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和)

    POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和) 题意分析 卡卡屋前有一株苹果树,每年秋天,树上长了许多苹果.卡卡很喜欢苹果.树上有N个节点,卡卡给他们编号1到N,根 ...

  3. HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对)

    HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对) 题意分析 给出n个数的序列,a1,a2,a3--an,ai∈[0,n-1],求环序列中逆序对 ...

  4. hdu 1166线段树 单点更新 区间求和

    敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  5. hdu1166(线段树单点更新&区间求和模板)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1166 题意:中文题诶- 思路:线段树单点更新,区间求和模板 代码: #include <iost ...

  6. hdu2795(线段树单点更新&区间最值)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2795 题意:有一个 h * w 的板子,要在上面贴 n 条 1 * x 的广告,在贴第 i 条广告时要 ...

  7. hdu1394(枚举/树状数组/线段树单点更新&区间求和)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1394 题意:给出一个循环数组,求其逆序对最少为多少: 思路:对于逆序对: 交换两个相邻数,逆序数 +1 ...

  8. HDU 1166 敌兵布阵(线段树点更新区间求和裸题)

    Problem Description C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任 ...

  9. POJ 2892 Tunnel Warfare(线段树单点更新区间合并)

    Tunnel Warfare Time Limit: 1000MS   Memory Limit: 131072K Total Submissions: 7876   Accepted: 3259 D ...

  10. HDU 3308 LCIS(线段树单点更新区间合并)

    LCIS Given n integers. You have two operations: U A B: replace the Ath number by B. (index counting ...

随机推荐

  1. spring mvc多环境下配置文件的设置

    在实际开发时经常需要把一些配置信息写在配置文件,比如mysql的主机地址.端口号.用户名和密码等.另外,在开发代码时可能用一套配置参数,而部署到测试环境时又会用另一套配置参数,测试完毕再部署到线上环境 ...

  2. Python 日期和时间_python 当前日期时间_python日期格式化

    Python 日期和时间_python 当前日期时间_python日期格式化 Python程序能用很多方式处理日期和时间,转换日期格式是一个常见的功能. Python 提供了一个 time 和 cal ...

  3. Mysql优化系列之数据类型优化

    本篇是优化系列的第一篇:数据类型 为了不产生赘述,尽量用简洁的语言来描述. 在选择数据类型之前,首先要知道几个原则: 更小的通常更好 尽量使用可以正确存储数据的最小数据类型.更小的数据类型意味着更快, ...

  4. vue组件间通信用例

    父组件传值给子组件 -- 以封装公用slide组件为例 父组件 <template> <section class="banner"> <slide ...

  5. Dubbo + Kryo 实现高速序列化

    Dubbo 中的序列化 Dubbo RPC 是 Dubbo 体系中最核心的一种高性能.高吞吐量的远程调用方式,可以称之为多路复用的 TCP 长连接调用: 长连接:避免了每次调用新建 TCP 连接,提高 ...

  6. 大半宿,封装了一个MP3播放器的类,写了个简陋的播放器

    用 winmm.lib 写的 封装不是很好,而且没有优化,效率可能有问题,但是现在几乎没有什么大问题 我用我封装的类,写了一个小播放器,界面上的所有功能都实现了,包括双击列表中的文件名,直接播放文件 ...

  7. linux 文件类型的颜色

    linux文件颜色的含义:蓝色代表目录 绿色代表可执行文件 红色表示压缩文件 浅蓝色表示链接文件 灰色表示其他文件 红色闪烁表示链接的文件有问题了 黄色表示设备文件 蓝色文件----------目录 ...

  8. PyTorch中的C++扩展

    今天要聊聊用 PyTorch 进行 C++ 扩展. 在正式开始前,我们需要了解 PyTorch 如何自定义module.这其中,最常见的就是在 python 中继承torch.nn.Module,用 ...

  9. 廖雪峰Java12maven基础-1maven入门-3构建流程

    maven是一个Java项目管理和构建工具: 标准化项目结构 标准化构建流程(编译.打包.发布) 依赖管理 Maven的构建流程 clean 删除所有编译生成的文件 compile 编译源码.编译测试 ...

  10. Java-slf4j:sfl4j

    ylbtech-Java-slf4j:sfl4j 1.返回顶部 1. SLF4J,即简单日志门面(Simple Logging Facade for Java),不是具体的日志解决方案,它只服务于各种 ...