题目链接

题解:

这道题目的难点在于如何考虑加法和乘法的”兼容“问题

定义两个标记 mul_lazy 和 add_lazy 分别表示加法和乘法

默认乘法优先 :因为算术运算中乘法优先级高,add_lazy标记可能还没有下放,如果默认加法优先,修改mul_lazy可能会导致错误

所以 每次乘的时候,子节点mul_lazy和add_lazy都一起乘父节点的mul_lazy,加的时候 子节点的add_lazy加父节点的add_lazy即可

push_down的更新操作代码

 1 struct node
 2 {
 3     int l,r;
 4     ll sum,add_lazy,mul_lazy;
 5     void update(ll mul,ll add)
 6     {
 7         if(mul!=1)
 8         {
 9             mul_lazy=(mul_lazy*mul)%mod;
10             add_lazy=(add_lazy*mul)%mod;
11             sum=(sum*mul)%mod;
12         }
13         if(add)
14         {
15             add_lazy=(add_lazy+add)%mod;
16             sum=(sum+((r-l+1)*add))%mod;
17         }
18     }
19 }tree[maxn<<2];

View Code

可以发现上面push_down的更新操作,加法和乘法可以合并

合并代码

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 typedef long long ll;
  4 const int maxn=1e5+5;
  5 int n,a[maxn],q,mod;
  6 struct node
  7 {
  8     int l,r;
  9     ll sum,add_lazy,mul_lazy;
 10     void update(ll mul,ll add)
 11     {
 12         sum=(sum*mul+add*(r-l+1))%mod;
 13         mul_lazy=(mul_lazy*mul)%mod;
 14         add_lazy=(add_lazy*mul+add)%mod;
 15
 16     }
 17 }tree[maxn<<2];
 18
 19 void push_up(int x)
 20 {
 21     tree[x].sum=(tree[x<<1].sum+tree[x<<1|1].sum)%mod;
 22 }
 23 void push_down(int x)
 24 {
 25     int mul=tree[x].mul_lazy;
 26     int add=tree[x].add_lazy;
 27     if(mul!=1 || add!=0)
 28     {
 29         tree[x<<1].update(mul,add);
 30         tree[x<<1|1].update(mul,add);
 31         tree[x].add_lazy=0;
 32         tree[x].mul_lazy=1;
 33     }
 34 }
 35 void build(int x,int l,int r)
 36 {
 37     tree[x].l=l,tree[x].r=r;
 38     tree[x].add_lazy=tree[x].sum=0;
 39     tree[x].mul_lazy=1;
 40     if(l==r)
 41     {
 42         tree[x].sum=a[l];
 43     }
 44     else
 45     {
 46         int mid=(l+r)>>1;
 47         build(x<<1,l,mid);
 48         build(x<<1|1,mid+1,r);
 49         push_up(x);
 50     }
 51 }
 52 void update(int x,int l,int r,ll val,int flag)
 53 {
 54     int L=tree[x].l,R=tree[x].r;
 55
 56     if(l<=L && R<=r)
 57     {
 58         if(flag==1)tree[x].update(val,0);
 59         else tree[x].update(1,val);
 60     }
 61     else
 62     {
 63         push_down(x);
 64         int mid=(L+R)>>1;
 65         if(mid>=l)update(x<<1,l,r,val,flag);
 66         if(mid<r)update(x<<1|1,l,r,val,flag);
 67         push_up(x);
 68     }
 69 }
 70 ll query(int x,int l,int r)
 71 {
 72     int L=tree[x].l,R=tree[x].r;
 73
 74     if(l<=L && R<=r)
 75     {
 76         return tree[x].sum%mod;
 77     }
 78     else
 79     {
 80         push_down(x);
 81         ll ans=0;
 82         int mid=(L+R)>>1;
 83         if(mid>=l)ans+=query(x<<1,l,r)%mod;
 84         if(mid<r)ans+=query(x<<1|1,l,r)%mod;
 85         push_up(x);
 86         return ans%mod;
 87     }
 88
 89 }
 90 int main()
 91 {
 92     scanf("%d%d%d",&n,&q,&mod);
 93     for(int i=1;i<=n;i++)
 94         scanf("%d",&a[i]);
 95     build(1,1,n);
 96     for(int i=1;i<=q;i++)
 97     {
 98         int l,r,op;
 99         ll val;
100         scanf("%d",&op);
101         if(op==1)
102         {
103             scanf("%d%d%lld",&l,&r,&val);
104             update(1,l,r,val,op);
105         }
106         else if(op==2)
107         {
108             scanf("%d%d%lld",&l,&r,&val);
109             update(1,l,r,val,op);
110         }
111         else
112         {
113             scanf("%d%d",&l,&r);
114             printf("%lld\n",query(1,l,r));
115         }
116
117
118     }
119     return 0;
120 }

View Code

代码:

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 typedef long long ll;
  4 const int maxn=1e5+5;
  5 int n,a[maxn],q,mod;
  6 struct node
  7 {
  8     int l,r;
  9     ll sum,add_lazy,mul_lazy;
 10     void update(ll mul,ll add)
 11     {
 12         if(mul!=1)
 13         {
 14             mul_lazy=(mul_lazy*mul)%mod;
 15             add_lazy=(add_lazy*mul)%mod;
 16             sum=(sum*mul)%mod;
 17         }
 18         if(add)
 19         {
 20             add_lazy=(add_lazy+add)%mod;
 21             sum=(sum+((r-l+1)*add))%mod;
 22         }
 23         ///合并代码
 24         /*
 25         sum=(sum*mul+add*(r-l+1))%mod;
 26         mul_lazy=(mul_lazy*mul)%mod;
 27         add_lazy=(add_lazy*mul+add)%mod;
 28         */
 29
 30     }
 31 }tree[maxn<<2];
 32
 33 void push_up(int x)
 34 {
 35     tree[x].sum=(tree[x<<1].sum+tree[x<<1|1].sum)%mod;
 36 }
 37 void push_down(int x)
 38 {
 39     int mul=tree[x].mul_lazy;
 40     int add=tree[x].add_lazy;
 41     if(mul!=1 || add!=0)
 42     {
 43         tree[x<<1].update(mul,add);
 44         tree[x<<1|1].update(mul,add);
 45         tree[x].add_lazy=0;
 46         tree[x].mul_lazy=1;
 47     }
 48 }
 49 void build(int x,int l,int r)
 50 {
 51     tree[x].l=l,tree[x].r=r;
 52     tree[x].add_lazy=tree[x].sum=0;
 53     tree[x].mul_lazy=1;
 54     if(l==r)
 55     {
 56         tree[x].sum=a[l];
 57     }
 58     else
 59     {
 60         int mid=(l+r)>>1;
 61         build(x<<1,l,mid);
 62         build(x<<1|1,mid+1,r);
 63         push_up(x);
 64     }
 65 }
 66 void update(int x,int l,int r,ll val,int flag)
 67 {
 68     int L=tree[x].l,R=tree[x].r;
 69
 70     if(l<=L && R<=r)
 71     {
 72         if(flag==1)tree[x].update(val,0);
 73         else tree[x].update(1,val);
 74     }
 75     else
 76     {
 77         push_down(x);
 78         int mid=(L+R)>>1;
 79         if(mid>=l)update(x<<1,l,r,val,flag);
 80         if(mid<r)update(x<<1|1,l,r,val,flag);
 81         push_up(x);
 82     }
 83 }
 84 ll query(int x,int l,int r)
 85 {
 86     int L=tree[x].l,R=tree[x].r;
 87
 88     if(l<=L && R<=r)
 89     {
 90         return tree[x].sum%mod;
 91     }
 92     else
 93     {
 94         push_down(x);
 95         ll ans=0;
 96         int mid=(L+R)>>1;
 97         if(mid>=l)ans+=query(x<<1,l,r)%mod;
 98         if(mid<r)ans+=query(x<<1|1,l,r)%mod;
 99         push_up(x);
100         return ans%mod;
101     }
102
103 }
104 int main()
105 {
106     scanf("%d%d%d",&n,&q,&mod);
107     for(int i=1;i<=n;i++)
108         scanf("%d",&a[i]);
109     build(1,1,n);
110     for(int i=1;i<=q;i++)
111     {
112         int l,r,op;
113         ll val;
114         scanf("%d",&op);
115         if(op==1)
116         {
117             scanf("%d%d%lld",&l,&r,&val);
118             update(1,l,r,val,op);
119         }
120         else if(op==2)
121         {
122             scanf("%d%d%lld",&l,&r,&val);
123             update(1,l,r,val,op);
124         }
125         else
126         {
127             scanf("%d%d",&l,&r);
128             printf("%lld\n",query(1,l,r));
129         }
130
131
132     }
133     return 0;
134 }

View Code

转载于:https://www.cnblogs.com/j666/p/11508889.html

线段树——区间累加、区间累乘、区间求和相关推荐

  1. 线段树线段树的创建线段树的查询单节点更新区间更新

    目录 线段树 什么是线段树? 线段树的创建 线段树的查询 单节点更新 区间更新 未完待续 线段树 实现问题:常用于求数组区间最小值 时间复杂度:(1).建树复杂度:nlogn.(2).线段树算法复杂度 ...

  2. 【线段树】HDU 3397 Sequence operation 区间合并

    操作 Change operations: 0 a b change all characters into '0's in [a , b] 1 a b change all characters i ...

  3. 线段树优化建图详解——区间连边之技巧,吊打紫题之利器

    我们从一道例题开始. CF786B Description Solution 朴素解法: 暴力连边+最短路 对于每次连边操作,我们逐一连边,最后在图上跑一遍单源最短路径算法即可. 时间复杂度 O ( ...

  4. 线段树(成段更新,区间求和lazy操作 )

    hdu1556 Color the ball Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/O ...

  5. 题目敌兵布阵-------线段树(单点修改查询,区间修改查询)

    C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任务就是要监视这些工兵营地的活动情况.由于 ...

  6. 线段树POJ3468(成段更新,区间求和)

    题目:A Simple Problem with Integers #include <stdio.h> #define N 111111 #define LL long long #de ...

  7. HDU-1754 线段树的节点更新,储存区间的最大值

    很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少.  这让很多学生很反感. 不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模拟老师的询问.当然,老师 ...

  8. 线段树为什么要开四倍区间大小的数组

    我的想法是,不能理解它,那就记住它!! 但是这里有大佬的想法,欢迎参观:https://blog.csdn.net/smoggyxhdz/article/details/78895672

  9. szu 寒训个人复习第一天 线段树入门单点修改,区间修改,以及线段树的扩展运用[线段树+dp][区间最大公约数]

    寒讯内容有点过多(其实是我太菜了)水一波怕忘了(人老了)**什么是线段树** 线段树是本蒟蒻感觉用处特别大的算法 那么线段树上面的节点表示什么意思呢? 线段树,上面的节点表示一个区间,父亲节点表示的区 ...

  10. HDU - 3667 Hotel(线段树+区间合并)

    题目链接:点击查看 题目大意:给出n个连续的空房间,依次进行m个操作,操作一是查询操作,查询在总区间内的一段连续的长度为x的空房间,并 且该位置要靠左,如果查询到返回最左边的端点,并将其占用,找不到返 ...

最新文章

  1. oracle votedisk 参数,11g r2 rac votedisk 及 ocr 磁盘破坏后,基于ocr备份的恢复步骤
  2. 「高并发秒杀」java课程设计报告模板
  3. 辨析Java与Javascript
  4. 1040 Longest Symmetric String (25 分)【难度: 一般 / 知识点: 最长回文子串】
  5. 2013ACM暑假集训总结-致将走上大三征途的我
  6. 数据结构与算法(C++)– 贪婪算法(Greedy algorithm)
  7. 关掉linux下的讨厌的beep声
  8. cocos2d-x游戏实例(3)-获得地图索引
  9. json 取值判断_【收藏级】.NETCore3.1中的Json互操作解读
  10. java学习(34):巩固练习
  11. c语言while求a和b的和程序,数据结构实验1_C语言_输入集合A和B求并集、交集、差集(while +...
  12. 中国糖和甜味剂市场趋势报告、技术动态创新及市场预测
  13. 计算机在生产作业管理,作业管理
  14. windows环境下面安装neo4j出错记录
  15. title或alt自动换行
  16. CSS3渐变(Gradients)-线性渐变
  17. 计算机关机又自动重启,电脑关机后自动重启是什么原因?Win10关机变重启原因及解决方法...
  18. 雷达系统和雷达信号分析02
  19. 什么是蜂窝移动网络?
  20. python计算学习,《统计学习方法》的Python实现:(1)感知机

热门文章

  1. 前端代码拆分的意义,以及如何拆分代码,文件拆分--前端教学文-f
  2. 如何用 Python 和循环神经网络预测严重交通拥堵?
  3. vb限制文本框输入内容长度_限制VB文本框输入的代码
  4. 3D打印切片软件CuraEngine介绍 windows版本
  5. 自建CA证书搭建https服务器
  6. 14. 深度解读ARM新架构:大核进取、小核摆烂?
  7. C语言俄罗斯方块(新版本完整代码)
  8. 《研磨设计模式》 配套源代码
  9. java内存模型——JMM理解
  10. JavaScript原生读取json文件