【洛谷 p3373】模板-线段树 2(数据结构--线段树)
题意:已知一个数列,你需要进行下面三种操作:1.将某区间每一个数加上x;2.将某区间每一个数乘上x;3.求出某区间每一个数的和。
解法:(唉 :-(,这题卡住我了......)对于加法和乘法的混合操作,lazy 标记记为 add , mul。
我们可以把运算全部化为 x*mul+add*(r-l+1) 的模型,其中它的运算有2种情况:
1.当前为加法,(x*mul+add*(r-l+1))+add'*(r-l+1) → (x*mul)+(add+add')*(r-l+1),也就是 add+=add';
2.当前为乘法,(x*mul+add*(r-l+1))*mul' → (x*mul*mul')+(add*(r-l+1)*mul'),也就是 mul*=mul', add*=mul'。
1 #include<cstdio>
2 #include<cstdlib>
3 #include<cstring>
4 #include<iostream>
5 using namespace std;
6 #define N 100010
7 typedef long long LL;
8
9 int n,m,P,len=0;
10 struct node
11 {
12 int l,r,lc,rc;
13 LL d,mul,add;
14 }a[2*N];
15
16 void build(int l,int r)
17 {
18 int x=++len;
19 a[x].l=l,a[x].r=r,a[x].d=0;
20 a[x].lc=a[x].rc=-1;
21 a[x].mul=1,a[x].add=0;
22 if (l<r)
23 {
24 int mid=(l+r)>>1;
25 a[x].lc=len+1,build(l,mid);
26 a[x].rc=len+1,build(mid+1,r);
27 }
28 }
29 void Pdown(int x,LL mul,LL add)
30 {
31 a[x].d=((a[x].d*mul)%P+(add*(a[x].r-a[x].l+1)%P))%P;//r-l+1
32 a[x].mul=(a[x].mul*mul)%P;
33 a[x].add=((a[x].add*mul)%P+add)%P;
34 }
35 void updata(int x)
36 {
37 if (a[x].mul==1 && !a[x].add) return;
38 int lc=a[x].lc,rc=a[x].rc;
39 if (lc!=-1) Pdown(lc,a[x].mul,a[x].add);
40 if (rc!=-1) Pdown(rc,a[x].mul,a[x].add);
41 a[x].mul=1,a[x].add=0;
42 }
43 void addi(int x,int l,int r,LL d)
44 {
45 if (a[x].l==l && a[x].r==r)
46 {
47 a[x].d=(a[x].d+d*(r-l+1))%P;//r-l+1
48 a[x].add=(a[x].add+d)%P;
49 return;
50 }
51 updata(x);
52 int lc=a[x].lc,rc=a[x].rc,mid=(a[x].l+a[x].r)>>1;
53 if (r<=mid) addi(lc,l,r,d);
54 else if (l>mid) addi(rc,l,r,d);
55 else addi(lc,l,mid,d),addi(rc,mid+1,r,d);
56 a[x].d=(a[lc].d+a[rc].d)%P;//only d
57 }
58 void multi(int x,int l,int r,LL d)
59 {
60 if (a[x].l==l && a[x].r==r)
61 {
62 a[x].d=(a[x].d*d)%P;
63 a[x].mul=(a[x].mul*d)%P,a[x].add=(a[x].add*d)%P;
64 return;
65 }
66 updata(x);
67 int lc=a[x].lc,rc=a[x].rc,mid=(a[x].l+a[x].r)>>1;
68 if (r<=mid) multi(lc,l,r,d);
69 else if (l>mid) multi(rc,l,r,d);
70 else multi(lc,l,mid,d),multi(rc,mid+1,r,d);
71 a[x].d=(a[lc].d+a[rc].d)%P;
72 }
73 LL query(int x,int l,int r)
74 {
75 updata(x);
76 if (a[x].l==l && a[x].r==r) return a[x].d;
77 int lc=a[x].lc,rc=a[x].rc,mid=(a[x].l+a[x].r)>>1;
78 if (r<=mid) return query(lc,l,r)%P;//%P
79 else if (l>mid) return query(rc,l,r)%P;
80 else return (query(lc,l,mid)+query(rc,mid+1,r))%P;
81 }
82 int main()
83 {
84 LL d; int x,y,k;
85 scanf("%d%d%d",&n,&m,&P);
86 build(1,n);
87 for (int i=1;i<=n;i++)
88 {
89 scanf("%lld",&d);
90 addi(1,i,i,d);
91 }
92 while (m--)
93 {
94 scanf("%d%d%d",&k,&x,&y);
95 if (x>y) {int t;t=x,x=y,y=t;}
96 if (k==1)
97 {
98 scanf("%lld",&d);
99 multi(1,x,y,d%P);
100 }
101 else if (k==2)
102 {
103 scanf("%lld",&d);
104 addi(1,x,y,d%P);
105 }
106 else printf("%lld\n",query(1,x,y));
107 }
108 return 0;
109 }
【洛谷 p3373】模板-线段树 2(数据结构--线段树)的更多相关文章
- 洛谷P3373 [模板]线段树 2(区间增减.乘 区间求和)
To 洛谷.3373 [模板]线段树2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格 ...
- 线段树_区间加乘(洛谷P3373模板)
题目描述 如题,已知一个数列,你需要进行下面三种操作: 1.将某区间每一个数乘上x 2.将某区间每一个数加上x 3.求出某区间每一个数的和 输入格式: 第一行包含三个整数N.M.P,分别表示该数列数字 ...
- 洛谷 P3373 【模板】线段树 2
洛谷 P3373 [模板]线段树 2 洛谷传送门 题目描述 如题,已知一个数列,你需要进行下面三种操作: 将某区间每一个数乘上 xx 将某区间每一个数加上 xx 求出某区间每一个数的和 输入格式 第一 ...
- 【洛谷5439】【XR-2】永恒(树链剖分,线段树)
[洛谷5439][XR-2]永恒(树链剖分,线段树) 题面 洛谷 题解 首先两个点的\(LCP\)就是\(Trie\)树上的\(LCA\)的深度. 考虑一对点的贡献,如果这两个点不具有祖先关系,那么这 ...
- 洛谷P3834 [模板]可持久化线段树1(主席树) [主席树]
题目传送门 可持久化线段树1(主席树) 题目背景 这是个非常经典的主席树入门题——静态区间第K小 数据已经过加强,请使用主席树.同时请注意常数优化 题目描述 如题,给定N个正整数构成的序列,将对于指定 ...
- LCT总结——概念篇+洛谷P3690[模板]Link Cut Tree(动态树)(LCT,Splay)
为了优化体验(其实是强迫症),蒟蒻把总结拆成了两篇,方便不同学习阶段的Dalao们切换. LCT总结--应用篇戳这里 概念.性质简述 首先介绍一下链剖分的概念(感谢laofu的讲课) 链剖分,是指一类 ...
- 【洛谷4219】[BJOI2014]大融合(线段树分治)
题目: 洛谷4219 分析: 很明显,查询的是删掉某条边后两端点所在连通块大小的乘积. 有加边和删边,想到LCT.但是我不会用LCT查连通块大小啊.果断弃了 有加边和删边,还跟连通性有关,于是开始yy ...
- Bzoj1018/洛谷P4246 [SHOI2008]堵塞的交通(线段树分治+并查集)
题面 Bzoj 洛谷 题解 考虑用并查集维护图的连通性,接着用线段树分治对每个修改进行分治. 具体来说,就是用一个时间轴表示图的状态,用线段树维护,对于一条边,我们判断如果他的存在时间正好在这个区间内 ...
- 洛谷 P1083 借教室【二分+差分/线段树】
二分mid,然后用1~mid的操作在差分序列上加减,最后把差分序列前缀和起来,看是否有有超过初始r值的 #include<iostream> #include<cstdio> ...
- 洛谷 P5044 - [IOI2018] meetings 会议(笛卡尔树+DP+线段树)
洛谷题面传送门 一道笛卡尔树的 hot tea. 首先我们考虑一个非常 naive 的区间 DP:\(dp_{l,r}\) 表示区间 \([l,r]\) 的答案,那么我们考虑求出 \([l,r]\) ...
随机推荐
- Centos 6 下安装 OSSEC-2.8.1 邮件告警 (二)
Ossec 配置邮件通知 ## 1 安装软件包: yum install -y sendmail mailx cyrus-sasl cyrus-sasl-plain #安装postfix邮件相关的软件 ...
- wpf 在不同DPI下如何在DrawingVisual中画出清晰的图形
环境Win10 VS2017 .Net Framework4.7.1 本文仅讨论在DrawingVisual中进行的画图. WPF单位,系统DPI,显示器DPI三者的定义及关系 WPF单位:一 ...
- 18.java设计模式之中介者模式
基本需求 智能家庭包括各种设备,闹钟.咖啡机.电视机.窗帘等 要看电视时,各个设备可以协同工作,自动完成看电视的准备工作,比如流程为:闹铃响起->咖啡机开始做咖啡->窗帘自动落下-> ...
- 【Oracle】add_months()函数介绍
add_months 函数主要是对日期函数进行操作,举例子进行说明 add_months 有两个参数,第一个参数是日期,第二个参数是对日期进行加减的数字(以月为单位的) 如:3个月以后的时间,可以用下 ...
- MySQL全面瓦解17:触发器相关
关于触发器 现实开发中我们经常会遇到这种情况,比如添加.删除和修改信息的时候需要记录日志,我们就要在完成常规的数据库逻辑操作之后再去写入日志表,这样变成了两步操作,更复杂了. 又比如删除一个人员信息的 ...
- kubernets之服务发现
一 服务与pod的发现 1.1 服务发现pod是很显而易见的事情,通过简称pod的标签是否和服务的标签一致即可,但是pod是如何发现服务的呢?这个问题其实感觉比较多余,但是接下来你就可能不这么想了 ...
- MyBatis初级实战之四:druid多数据源
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- BeetleX大数据之产品分析服务
数据规模过于庞大?数据标签过多难以管理?增加新的分析维度需要配置?这些beetlex.io都能轻松解决,即导即用,数据标签自动管理,轻易实现多种维度数据分析处理.接下介绍BeetleX针对产品 ...
- Ubuntu安装记录
好吧,这成功地让我想起了那些边肯红薯边黑苹果的早晨······ 本人纯属Windows用腻,后期请大佬多多指教 前面因为没U盘而碰壁的内容在此不说,接下来因为太兴奋,关于安装U盘制作没记录什么.最终, ...
- 前端面试之HTTP状态码!
前端面试之HTTP协议的东西! 一次HTTP请求的流程! HTTP 状态码 成功响应(200–299) 状态码 含义 200 请求成功 201 该请求已成功,并因此创建了一个新的资源.这通常是在POS ...