To 洛谷.3373 [模板]线段树2

题目描述

如题,已知一个数列,你需要进行下面两种操作:

1.将某区间每一个数加上x

2.将某区间每一个数乘上x

3.求出某区间每一个数的和

输入输出格式

输入格式:

第一行包含三个整数N、M、P,分别表示该数列数字的个数、操作的总个数和模数。

第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值。

接下来M行每行包含3或4个整数,表示一个操作,具体如下:

操作1: 格式:1 x y k 含义:将区间[x,y]内每个数乘上k

操作2: 格式:2 x y k 含义:将区间[x,y]内每个数加上k

操作3: 格式:3 x y 含义:输出区间[x,y]内每个数的和对P取模所得的结果

输出格式:

输出包含若干行整数,即为所有操作3的结果。

输入输出样例

输入样例#1:

5 5 38
1 5 4 2 3
2 1 4 1
3 2 5
1 2 4 2
2 3 5 5
3 1 4
输出样例#1:

17
2

说明

时空限制:1000ms,128M

数据规模:

对于30%的数据:N<=8,M<=10

对于70%的数据:N<=1000,M<=10000

对于100%的数据:N<=100000,M<=100000

(数据已经过加强^_^)

样例说明:

故输出应为17、2(40 mod 38=2)

代码:

 #include<cstdio>
#define LL long long//开long long!!
using namespace std;
const int N=; int n,m,mod;
LL Sum[N<<],LazySum[N<<],LazyMult[N<<]; void read(int &now)
{
now=;int f=;char c=getchar();
while(c<''||c>'')
{
if(c=='-')f=-;
c=getchar();
}
while(c>=''&&c<='')now=(now<<)+(now<<)+c-'',c=getchar();
now*=f;
} void PushUp(int rt)
{
Sum[rt]=Sum[rt<<]+Sum[rt<<|];
}
void PushDown(int rt,int m)
{
if(LazyMult[rt]!=)//乘法标记需不为1
{
Sum[rt<<]*=LazyMult[rt];Sum[rt<<]%=mod;
Sum[rt<<|]*=LazyMult[rt];Sum[rt<<|]%=mod;
LazyMult[rt<<]*=LazyMult[rt];LazyMult[rt<<]%=mod;
LazyMult[rt<<|]*=LazyMult[rt];LazyMult[rt<<|]%=mod;
LazySum[rt<<]*=LazyMult[rt];LazySum[rt<<]%=mod;
LazySum[rt<<|]*=LazyMult[rt];LazySum[rt<<|]%=mod;
LazyMult[rt]=;
}
if(LazySum[rt])
{
Sum[rt<<]+=LazySum[rt]*(m-(m>>));Sum[rt<<]%=mod;
Sum[rt<<|]+=LazySum[rt]*(m>>);Sum[rt<<|]%=mod;
LazySum[rt<<]+=LazySum[rt];LazySum[rt<<]%=mod;
LazySum[rt<<|]+=LazySum[rt];LazySum[rt<<|]%=mod;
LazySum[rt]=;
}
}
void Build(int l,int r,int rt)
{
LazySum[rt]=;LazyMult[rt]=;
if(l==r)
{
scanf("%lld",&Sum[rt]);
return;
}
int m=(l+r)>>;
Build(l,m,rt<<);
Build(m+,r,rt<<|);
PushUp(rt);
}
void ModifyAdd(int l,int r,int rt,int L,int R,int v)
{
if(L<=l && r<=R)
{
Sum[rt]+=v*(r-l+);Sum[rt]%=mod;
LazySum[rt]+=v;LazySum[rt]%=mod;
return;
}
PushDown(rt,r-l+);
int m=(l+r)>>;
if(L<=m) ModifyAdd(l,m,rt<<,L,R,v);
if(m<R) ModifyAdd(m+,r,rt<<|,L,R,v);
PushUp(rt);
}
void ModifyMult(int l,int r,int rt,int L,int R,int v)
{
if(L<=l && r<=R)
{//对于懒惰标记 乘法会影响加法,但加法并不会影响乘法
//所以加法标记必须也乘
Sum[rt]*=v;Sum[rt]%=mod;
LazySum[rt]*=v;LazySum[rt]%=mod;//更新乘法的同时更新加法
LazyMult[rt]*=v;LazyMult[rt]%=mod;
return;
}
PushDown(rt,r-l+);
int m=(l+r)>>;
if(L<=m) ModifyMult(l,m,rt<<,L,R,v);
if(m<R) ModifyMult(m+,r,rt<<|,L,R,v);
PushUp(rt);
}
LL QuerySum(int l,int r,int rt,int L,int R)
{
if(L<=l && r<=R) return Sum[rt];
PushDown(rt,r-l+);
int m=(l+r)>>;LL res=;
if(L<=m) res+=QuerySum(l,m,rt<<,L,R),res%=mod;
if(m<R) res+=QuerySum(m+,r,rt<<|,L,R),res%=mod;
return res;
} int main()
{
read(n);read(m);read(mod);
Build(,n,);
for(int i=;i<=m;i++)
{
int opt,a,b;
read(opt);read(a);read(b);
if(opt==)
{
int k;read(k);
ModifyMult(,n,,a,b,k);
}
else if(opt==)
{
int k;read(k);
ModifyAdd(,n,,a,b,k);
}
else
printf("%lld\n",QuerySum(,n,,a,b));
}
return ;
}

洛谷P3373 [模板]线段树 2(区间增减.乘 区间求和)的更多相关文章

  1. 线段树_区间加乘(洛谷P3373模板)

    题目描述 如题,已知一个数列,你需要进行下面三种操作: 1.将某区间每一个数乘上x 2.将某区间每一个数加上x 3.求出某区间每一个数的和 输入格式: 第一行包含三个整数N.M.P,分别表示该数列数字 ...

  2. 洛谷P3374(线段树)(询问区间和,支持单点修改)

    洛谷P3374 //询问区间和,支持单点修改 #include <cstdio> using namespace std; ; struct treetype { int l,r,sum; ...

  3. 洛谷 - P1198 - 最大数 - 线段树

    https://www.luogu.org/problemnew/show/P1198 要问区间最大值,肯定是要用线段树的,不能用树状数组.(因为没有逆元?但是题目求的是最后一段,可以改成类似前缀和啊 ...

  4. 洛谷 P2391 白雪皑皑 线段树+优化

    题目描述: 现在有 \(N\) 片雪花排成一列. Pty 要对雪花进行$ M $次染色操作,第 \(i\)次染色操作中,把\((i*p+q)%N+1\) 片雪花和第\((i*q+p)%N+1\)片雪花 ...

  5. 【洛谷】【线段树】P1471 方差

    [题目背景:] 滚粗了的HansBug在收拾旧数学书,然而他发现了什么奇妙的东西. [题目描述:] 蒟蒻HansBug在一本数学书里面发现了一个神奇的数列,包含N个实数.他想算算这个数列的平均数和方差 ...

  6. 【洛谷】【线段树】P1047 校门外的树

    [题目描述:] 某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米.我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置:数轴上的每个整数点,即0,1,2,……,L ...

  7. 【洛谷】【线段树】P1886 滑动窗口

    [题目描述:] 现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口.现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最大值和最小值. [输入格式:] 输入一共 ...

  8. 【洛谷】【线段树】P3353 在你窗外闪耀的星星

    [题目描述:] /* 飞逝的的时光不会模糊我对你的记忆.难以相信从我第一次见到你以来已经过去了3年.我仍然还生动地记得,3年前,在美丽的集美中学,从我看到你微笑着走出教室,你将头向后仰,柔和的晚霞照耀 ...

  9. 洛谷 P5280 - [ZJOI2019]线段树(线段树+dp,神仙题)

    题面传送门 神仙 ZJOI,不会做啊不会做/kk Sooke:"这八成是考场上最可做的题",由此可见 ZJOI 之毒瘤. 首先有一个非常显然的转化,就是题目中的"将线段树 ...

随机推荐

  1. 转载-通俗理解BN(Batch Normalization)

    转自:参数优化方法 1. 深度学习流程简介 1)一次性设置(One time setup)          -激活函数(Activation functions) - 数据预处理(Data Prep ...

  2. machine_desc结构体【转】

    转自:http://blog.csdn.net/myarrow/article/details/8609564 1. 简介 内核提供了一个重要的结构体struct machine_desc ,这个结构 ...

  3. setInterval的用法

    function show1(){    console.log("每隔1秒显示一次");}function show2(str){    console.log(str);}se ...

  4. Python3学习笔记23-StringIO和BytesIO

    StringIO 很多时候数据读取不一定是文件,也可以在内存中 StringIO顾名思义就是在内存中读写str 要把str写入StringIO,我们需要先创建一个StringIO,然后像文件一样写入即 ...

  5. 出现“error LNK1169: 找到一个或多个多重定义的符号”的原因

    或许,有人真的会这样写程序吧...所以才会碰到如下哥们提出的问题. https://zhidao.baidu.com/question/131426210.html 出现这种问题的原因链接中的最佳答案 ...

  6. ubuntu数据库迁移

    环境:ubuntu16.04 简介:本教程演示如何从旧数据库服务器服转移到另一个新服务器. 场景:假设你有自己的云服务器安装了WordPress站点,你为了更多的内存和处理能力想升级到新的服务器. 操 ...

  7. 读SRE Google运维解密有感(四)-聊聊问题排查

    前言 这是读“SRE Google运维解密”有感第四篇,之前的文章可访问www.addops.cn来查看.今天我们来聊聊“问题排查”这个话题,本人到目前为止还在参与一线运维的工作,遇到过很多“稀奇古怪 ...

  8. nagios系列(五)之nagios图形显示的配置及自定义插件检测密码是否修改详解

    nagios图形显示的配置 在服务端安装相关软件 #1.图形显示管理的依赖库 yum install cairo pango zlib zlib-devel freetype freetype-dev ...

  9. SQL中的 if 结构和循环(while)结构

  10. SpringMVC(4.1):Controller接口控制器详解(1)

    原文出处: 张开涛 4.1.Controller简介 Controller控制器,是MVC中的部分C,为什么是部分呢?因为此处的控制器主要负责功能处理部分: 1.收集.验证请求参数并绑定到命令对象: ...