大意:一个数组,三个操作,第一种是区间[a,b]每个数乘乘,第二种是区间[a,b]每个数加c,第三种是查询[a,b]区间的和并对p取摸。

两种操作就不能简单的只往下传标记。每次传乘法标记时,要把加法标记同时乘上乘法标记,例如某个区间先进来一个加法标记add,之后又进来一个乘法标记mul。

那么结果为(x+add)*mul=x*mul+add*mul。这样向下传标记的时候就相对独立。递归边界更新加法标记之前先乘上该节点的mul,左右儿子down的时候先将儿子的add乘上本节点的mul。

最后说一下sum,比如本节点的存在加法标记x和乘法标记y,并且是先加上x,再乘上y,则左儿子的sum要更新为(sum+x)*y。由于乘法标记传到本节点的时候更新了加法标记,x =x*y,所以sum[o<<1]=(左区间的长度*x)+sum[o<<1]*y。

 #include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std; typedef long long LL; #define N 100010 int n,m;
int askd,al,ar,ask;
LL p; LL add[N<<],sum[N<<],mul[N<<]; void pushup(int now)
{
sum[now]=(sum[now<<]+sum[now<<|])%p;
} void pushdown(int now,int d)
{
if (add[now]!= || mul[now]!=)
{
mul[now<<]=mul[now<<]*mul[now]%p;
mul[now<<|]=mul[now<<|]*mul[now]%p;
add[now<<]=(add[now]+add[now<<]*mul[now])%p;
add[now<<|]=(add[now]+add[now<<|]*mul[now])%p;
sum[now<<]=(add[now]*(d-(d>>))+sum[now<<]*mul[now])%p;
sum[now<<|]=(add[now]*(d>>)+sum[now<<|]*mul[now])%p;
add[now]=;
mul[now]=;
}
} void build(int nowl,int nowr,int now)
{
sum[now]=;
mul[now]=;
if (nowl==nowr)
{
scanf("%lld",&sum[now]);
return ;
}
int mid=(nowl+nowr)>>;
build(nowl,mid,now<<);
build(mid+,nowr,now<<|);
pushup(now);
} void updata_mul(int nowl,int nowr,int now,int l,int r,int c)
{
if (nowl>=l && nowr<=r)
{
add[now]=add[now]*c%p;
sum[now]=sum[now]*c%p;
mul[now]=mul[now]*c%p;
return ;
}
pushdown(now,nowr-nowl+);
int mid=(nowl+nowr)>>;
if (l<=mid)
updata_mul(nowl,mid,now<<,l,r,c);
if (r>mid)
updata_mul(mid+,nowr,now<<|,l,r,c);
pushup(now);
} void updata_add(int nowl,int nowr,int now,int l,int r,int c)
{
if (nowl>=l && nowr<=r)
{
add[now]=(add[now]+c)%p;
sum[now]=(sum[now]+c*(nowr-nowl+))%p;
return ;
}
pushdown(now,nowr-nowl+);
int mid=(nowl+nowr)>>;
if (l<=mid)
updata_add(nowl,mid,now<<,l,r,c);
if (r>mid)
updata_add(mid+,nowr,now<<|,l,r,c);
pushup(now);
} LL query(int nowl,int nowr,int now,int l,int r)
{
LL res();
if (nowl>=l && nowr<=r)
return sum[now];
pushdown(now,nowr-nowl+);
int mid=(nowl+nowr)>>;
if (l<=mid)
res=(res+query(nowl,mid,now<<,l,r))%p;
if (r>mid)
res=(res+query(mid+,nowr,now<<|,l,r))%p;
return res;
} int main()
{
scanf("%d%lld",&n,&p);
build(,n,);
scanf("%d",&m);
while (m--)
{
scanf("%d",&askd);
if (askd==)
{
scanf("%d%d%d",&al,&ar,&ask);
updata_mul(,n,,al,ar,ask);
}
if (askd==)
{
scanf("%d%d%d",&al,&ar,&ask);
updata_add(,n,,al,ar,ask);
}
if (askd==)
{
scanf("%d%d",&al,&ar);
printf("%lld\n",query(,n,,al,ar));
}
}
return ;
}

【bzoj1798】[Ahoi2009]Seq 维护序列seq的更多相关文章

  1. BZOJ1798: [Ahoi2009]Seq 维护序列seq[线段树]

    1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec  Memory Limit: 64 MBSubmit: 5504  Solved: 1937[Submit ...

  2. BZOJ 1798: [Ahoi2009]Seq 维护序列seq( 线段树 )

    线段树.. 打个 mul , add 的标记就好了.. 这个速度好像还挺快的...( 相比我其他代码 = = ) 好像是#35.. ---------------------------------- ...

  3. 1798: [Ahoi2009]Seq 维护序列seq

    1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec  Memory Limit: 64 MBSubmit: 2930  Solved: 1087[Submit ...

  4. bzoj 1798: [Ahoi2009]Seq 维护序列seq (线段树 ,多重标记下放)

    1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec  Memory Limit: 64 MBSubmit: 7773  Solved: 2792[Submit ...

  5. bzoj 1798: [Ahoi2009]Seq 维护序列seq 线段树 区间乘法区间加法 区间求和

    1798: [Ahoi2009]Seq 维护序列seq Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeO ...

  6. Bzoj 1798: [Ahoi2009]Seq 维护序列seq(线段树区间操作)

    1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec Memory Limit: 64 MB Description 老师交给小可可一个维护数列的任务,现在小可 ...

  7. BZOJ1798[Ahoi2009]Seq 维护序列seq 题解

    题目大意: 有长为N的数列,有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2)把数列中的一段数全部加一个值; (3)询问数列中的一段数的和,由于答案可能很大,你只需输出这个数模P的值. ...

  8. 【bzoj1798】[Ahoi2009]Seq 维护序列seq 线段树

    题目描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2)把数列中的一 ...

  9. 【分块】bzoj1798 [Ahoi2009]Seq 维护序列seq

    分块,打标记,维护两个标记:乘的 和 加的. 每次 区间乘的时候,对 乘标记 和 加标记 都 乘上那个值. 每次 区间加的时候 对 加标记 加上那个值. (ax+b)*v=axv+bv.开 long ...

  10. [bzoj1798][Ahoi2009]Seq 维护序列seq ([洛谷P3373]【模板】线段树 2)

    题目大意:有$n$个数,有$m$个操作,有三种: $1\;l\;r\;x:$把区间$[l,r]$内的数乘上$x$ $2\;l\;r\;x:$把区间$[l,r]$内的数加上$x$ $3\;l\;r:$询 ...

随机推荐

  1. P2P实现的原理

    为了项目的后期IM应用,最近在研究libjingle,中间看了也收集了很多资料,感慨网上很多资料要么太过于纠结协议(如STUN.ICE等)实现细节,要么中间有很多纰漏.最后去伪存真,归纳总结了一下,希 ...

  2. ''tensorflow.python.framework.errors_impl.ResourceExhaustedError: OOM when allocating tensor with shape[?]'' 错误分析

    这是tensorflow 一个经常性错误,错误的原因在于:显卡内存不够. 解决方法就是降低显卡的使用内存,途径有以下几种措施: 1 减少Batch 的大小 2 分析错误的位置,在哪一层出现显卡不够,比 ...

  3. CSU——2161: 漫漫上学路 最短路

    Description 众所周知,CSU(California State)University) 的上课地点距离学生公寓很远,对于爱睡懒觉的小Z来说,每天去上课就成了一件非常头疼的事,如果有早课的话 ...

  4. [JOYOI] 1052 没有上司的舞会

    / Joy OI / 题目列表 / 没有上司的舞会 题目限制 时间限制 内存限制 评测方式 题目来源 1000ms 131072KiB 标准比较器 Local 题目描述 Ural大学有N个职员,编号为 ...

  5. 利用Merge into 改写Update SQL 一例

    前言 客户说,生产系统最近CPU使用率经常达到100%,请DBA帮忙调查一下. 根据客户提供的情况描述及对应时间段,我导出AWR,发现如下问题: 11v41vaj06pjd :每次执行消耗2,378, ...

  6. 每日命令:(13)more

    more命令,功能类似 cat ,cat命令是整个文件的内容从上到下显示在屏幕上. more会以一页一页的显示方便使用者逐页阅读,而最基本的指令就是按空白键(space)就往下一页显示,按 b 键就会 ...

  7. LINUX:Contos7.0 / 7.2 LAMP+R 下载安装Php篇

    文章来源:http://www.cnblogs.com/hello-tl/p/7569071.html 更新时间:2017-09-21 16:03 简介 LAMP+R指Linux+Apache+Mys ...

  8. vim学习之旅01-文本搜索并高亮显示

    step 1:在linux终端新建一个test.txt文本文档:vim test.txt; 回车后打开编辑器: step 2:进入编辑状态(键盘"i")输入一段文本,退出编辑(键盘 ...

  9. POJ3107 树的重心

    题解:只不过如果有求多个点,输出所有方案. #include<cstring> #include<cmath> #include<iostream> #includ ...

  10. node.js 读取文件--createReadStream

    createReadStream 是fs模块里面读流的一个方法 这个方法基于fs模块的,所以我们先要引进fs模块 let fs=require("fs"); createReadS ...