P3373 【模板】线段树2 题解
【题目链接】P3373 【模板】线段树 2
【思路】
本题复杂在于有两个优先级不同的区间修改操作。考虑遵循乘法优先,那么维护两个懒标记mul(乘)和add(加),打加法标记按照普通方法,打乘法标记要注意把加法标记也乘一下要乘的数。加法标记的下传,要先把原标记乘上乘法标记(乘法优先)
举个例子:
假设一个长度为5的区间的和为25,现要把区间每个数加上5再乘上5,那么打乘法标记时,加法标记就应变为5*5=25,那么维护该区间的值时,这个区间的值就应该是25*5+5*5*5=250,类似于乘法分配律的思想。先乘后加也是一样的推导:打乘法标记时,加法标记变为0*5=0,后来加法打上标记5,维护区间值时,这个区间的值就应该是25*5+5*5=150。
【Code】
#include<iostream>
#include<cstdio>
using namespace std;
struct Segment_Tree{long long sum;long long mul,add;
}tree[500000];
long long a[100100],kk;
int p,n,m,op,ll,rr;
inline void build(int k,int l,int r){tree[k].add=0;tree[k].mul=1;if(l==r){tree[k].sum=a[l]%p;return;}int mid=(l+r)>>1;build(k<<1,l,mid);build(k<<1|1,mid+1,r);tree[k].sum=(tree[k<<1].sum+tree[k<<1|1].sum)%p;
}
inline void pushdown(int k,int l,int r){int mid=(l+r)>>1;tree[k<<1].sum=(tree[k<<1].sum*tree[k].mul+tree[k].add*(mid-l+1))%p;tree[k<<1|1].sum=(tree[k<<1|1].sum*tree[k].mul+tree[k].add*(r-mid))%p;if(tree[k].add){tree[k<<1].add=(tree[k<<1].add*tree[k].mul+tree[k].add)%p;tree[k<<1|1].add=(tree[k<<1|1].add*tree[k].mul+tree[k].add)%p;tree[k].add=0;}if(tree[k].mul!=1){tree[k<<1].mul=(tree[k<<1].mul*tree[k].mul)%p;tree[k<<1|1].mul=(tree[k<<1|1].mul*tree[k].mul)%p;tree[k].mul=1;}
}
inline long long Ask(int k,int l,int r,int x,int y){if(x>r||l>y)return 0;if(x<=l&&y>=r)return tree[k].sum;pushdown(k,l,r);int mid=(l+r)>>1;long long res=0;if(x<=mid)res+=Ask(k<<1,l,mid,x,y);if(y>mid)res+=Ask(k<<1|1,mid+1,r,x,y);return res%p;
}
inline void modify_add(int k,int l,int r,int x,int y,long long v){if(y<l||r<x)return;if(x<=l&&r<=y){tree[k].add=(tree[k].add+v)%p;tree[k].sum=(tree[k].sum+v*(r-l+1))%p;return;}pushdown(k,l,r);int mid=(l+r)>>1;if(x<=mid)modify_add(k<<1,l,mid,x,y,v);if(y>mid)modify_add(k<<1|1,mid+1,r,x,y,v);tree[k].sum=(tree[k<<1].sum+tree[k<<1|1].sum)%p;
}
inline void modify_mul(int k,int l,int r,int x,int y,long long v){if(y<l||r<x)return;if(x<=l&&r<=y){tree[k].mul=(tree[k].mul*v)%p;tree[k].sum=(tree[k].sum*v)%p;tree[k].add=(tree[k].add*v)%p;return;}pushdown(k,l,r);int mid=(l+r)>>1;if(x<=mid)modify_mul(k<<1,l,mid,x,y,v);if(y>mid)modify_mul(k<<1|1,mid+1,r,x,y,v);tree[k].sum=(tree[k<<1].sum+tree[k<<1|1].sum)%p;
}
int main(){scanf("%d%d%d",&n,&m,&p);for(register int i=1;i<=n;i++)scanf("%lld",&a[i]);build(1,1,n);for(register int i=1;i<=m;i++){scanf("%d",&op);if(op==1){scanf("%d%d%lld",&ll,&rr,&kk);modify_mul(1,1,n,ll,rr,kk);}else{if(op==2){scanf("%d%d%lld",&ll,&rr,&kk);modify_add(1,1,n,ll,rr,kk);}else{scanf("%d%d",&ll,&rr);printf("%lld\n",Ask(1,1,n,ll,rr));}}}return 0;
}
P3373 【模板】线段树2 题解相关推荐
- 洛谷 P3373 【模板】线段树 2 题解
洛谷 P3373 [模板]线段树 2 题解 题面 题目链接:[戳这里](https://www.luogu.org/problemnew/show/P3373) 题目描述 输入输出格式 输入输出样例 ...
- 洛谷(P3373)线段树加乘混合模板
题目链接:P3373 [模板]线段树 2 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 这道题目的意思很明确,就是要我们在线完成区间的乘和加运算并支持查询区间和的一个问题.处理这道 ...
- 蒟蒻君的刷题日记Day12(线段树专题T4):P8082 [COCI2011-2012#4] KEKS 线段树版题解
解题思路 看题解区的大佬们用的都是单调栈,本蒟蒻献上一篇线段树题解. 整个数最大,首先位数是确定的,则肯定优先考虑高位大小. 大体思路就是从前向后依次求出每一位的值(好像是废话). 对于第 iii 位 ...
- hdu3966 树链剖分点权模板+线段树区间更新/树状数组区间更新单点查询
点权树的模板题,另外发现树状数组也是可以区间更新的.. 注意在对链进行操作时方向不要搞错 线段树版本 #include<bits/stdc++.h> using namespace std ...
- NEFU OJ 1266-快乐的雨季-线段树【题解】
题目链接:problem-1266 快乐的雨季 简单说明: 模板题--线段树的区间更新(更新,不是替换).区间查询.没有什么难以理解的.值得注意的是,数据规模最大的情况下每个点会达到1e9这样子,那么 ...
- 洛谷 p3372 模板-线段树 1
题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.求出某区间每一个数的和 输入输出格式 输入格式: 第一行包含两个整数N.M,分别表示该数列数字的个数和操作的总个 ...
- Codeforces 671C Ultimate Weirdness of an Array 线段树 (看题解)
Ultimate Weirdness of an Array 写不出来, 日常好菜啊.. 考虑枚举GCD, 算出一共有多少个对 f(l, r) <= GCD, 我们用fuc[ i ] 表示的是在 ...
- Codeforces 213E Two Permutations 线段树 (看题解)
Two Permutations 关键是没想到按大小顺序把第二个排列一个一个加入线段树, 然后线段树维护整体的hash值, 得到的hs值减去一个sub 之后与, 第一个排列的hash值比较. #inc ...
- 算法模板——线段树6(二维线段树:区域加法+区域求和)(求助phile)
实现功能--对于一个N×M的方格,1:输入一个区域,将此区域全部值作加法:2:输入一个区域,求此区域全部值的和 其实和一维线段树同理,只是不知道为什么速度比想象的慢那么多,求解释...@acphile ...
最新文章
- linux 远程挂载摄像头_基于Linux的嵌入式网络摄像机设计
- [Nginx]nginx 配置实例-负载均衡
- 1495: 蛇行矩阵
- python中正确的输入语句_python中,输入简单的非法语句为什么显示不一致呢
- android获取网络视频缩略图,Android 获取视频(本地和网络)缩略图的解决方案
- javascript高级程序设计pdf_Java、C语言、Python、PHP、JavaScript五大编程语言,要学哪个?...
- python writelines_详解详解Python中writelines()方法的使用
- 倍福嵌入式控制器PLC各型号介绍
- 1.3 三种交换方式:电路交换、分组交换、报文交换
- 用计算机如何绘制流程图,电脑上怎么绘制流程图?电脑小白也能学会的流程图制作方法...
- Transformer Transducer 论文笔记
- CSS面试须知--盒子模型、浮动及定位
- 螣龙安科入侵感知:防火墙有哪些缺陷?
- 计算机二级msoffice必做题型,计算机二级MS Office考试 题型汇总附答案
- 个人博客搭建系列(一) 之 阿里云购买域名及解析对应ip地址
- 封装composer包包
- 步进电机控制(Proteus仿真+代码
- 5G系统——MICO模式
- mc服务器修改别人领地权限,我的世界领地权限设置 领地指令大全
- Excel-VBA操作文件四大方法
热门文章
- python爬取微信好友信息
- 从吃凉的就会肚子疼,不敢吃可爱多以下的雪糕,吃饱后去逛街肚子就会胀,到后来吃饭的时候就胃疼解决办法
- 【AE2019】Adobe_After_Effects_2019软件下载及安装教程
- SAP 标准成本、计划成本、目标成本、实际成本解析
- SharedPreferences的调教
- 计算机概论在线阅读,计算机科学概论(Python版)
- 功不唐捐——高兴的一天
- Java final String类的详细用法还有特性说明,自己也在学习.
- 配置 择时 sel stock
- Linux内核通知链(notifier chain)