【bzoj1798】[Ahoi2009]Seq 维护序列seq
大意:一个数组,三个操作,第一种是区间[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的更多相关文章
- BZOJ1798: [Ahoi2009]Seq 维护序列seq[线段树]
1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec Memory Limit: 64 MBSubmit: 5504 Solved: 1937[Submit ...
- BZOJ 1798: [Ahoi2009]Seq 维护序列seq( 线段树 )
线段树.. 打个 mul , add 的标记就好了.. 这个速度好像还挺快的...( 相比我其他代码 = = ) 好像是#35.. ---------------------------------- ...
- 1798: [Ahoi2009]Seq 维护序列seq
1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec Memory Limit: 64 MBSubmit: 2930 Solved: 1087[Submit ...
- bzoj 1798: [Ahoi2009]Seq 维护序列seq (线段树 ,多重标记下放)
1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec Memory Limit: 64 MBSubmit: 7773 Solved: 2792[Submit ...
- bzoj 1798: [Ahoi2009]Seq 维护序列seq 线段树 区间乘法区间加法 区间求和
1798: [Ahoi2009]Seq 维护序列seq Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeO ...
- Bzoj 1798: [Ahoi2009]Seq 维护序列seq(线段树区间操作)
1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec Memory Limit: 64 MB Description 老师交给小可可一个维护数列的任务,现在小可 ...
- BZOJ1798[Ahoi2009]Seq 维护序列seq 题解
题目大意: 有长为N的数列,有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2)把数列中的一段数全部加一个值; (3)询问数列中的一段数的和,由于答案可能很大,你只需输出这个数模P的值. ...
- 【bzoj1798】[Ahoi2009]Seq 维护序列seq 线段树
题目描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2)把数列中的一 ...
- 【分块】bzoj1798 [Ahoi2009]Seq 维护序列seq
分块,打标记,维护两个标记:乘的 和 加的. 每次 区间乘的时候,对 乘标记 和 加标记 都 乘上那个值. 每次 区间加的时候 对 加标记 加上那个值. (ax+b)*v=axv+bv.开 long ...
- [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:$询 ...
随机推荐
- 2.10.2 section元素
section元素 <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> & ...
- JAVA基础——IO流字符流
字符流 字节流提供了处理任何类型输入/输出操作的功能(因为对于计算机而言,一切都是0和1,只需把数据以字节形式表示就够了),但它们不可以直接操作Unicode字符,因为上一篇文章写了,一个Unicod ...
- 安装Vmware Tools出现错误
安装Vmware Tools出现: Before you can compile modules, you need to have the following installed... makegc ...
- 如何优雅的使用vue+Dcloud(Hbuild)开发混合app
如何优雅的使用vue+Dcloud(Hbuild)开发混合app 最近在做混合app,前端框架用的是vue,打包app使用的是Dcloud,不过在开发过程中有一点不爽的是,如果想使用Dcloud提供的 ...
- rbac组件之菜单操作(三)
菜单包括菜单列表,菜单列表不仅将菜单列出来,而且将每个菜单下的权限也列出来.菜单的添加.删除.修改. urls.py ... re_path(r'^menus/list/$', MenuView.as ...
- 零基础入门Python数据分析,只需要看懂这一张图,附下载链接!
摘要 在做数据分析的过程中,经常会想数据分析到底是什么?为什么要做数据数据分析?数据分析到底该怎么做?等这些问题.对于这些问题,一开始也只是有个很笼统的认识. 最近这两天,读了一下早就被很多人推荐的& ...
- 集训第六周 古典概型 期望 D题 Discovering Gold 期望
Description You are in a cave, a long cave! The cave can be represented by a 1 x N grid. Each cell o ...
- 从PDF复制到word(换行问题)
当我们从pdf文档中复制一部分内容到word的时候,pdf的自动换行会自动给文字添加换行,也就是一个回车,让文字另起一行,这样粘贴到word中的时候,word中也会有很多换行符,排版比较麻烦,需要一个 ...
- 用PowerPoint中的VB实现课件中的智能交互
http://www.duxiushan.net/index.asp?xAction=xReadNews&NewsID=294 我们使用PPT的目的只有一个,即更好地达成“沟通.演说.汇报.讲 ...
- 学习使用windows下类似iptables的防火墙软件
项目地址:http://wipfw.sourceforge.net一.下载地址:http://sourceforge.net/projects/wipfw/files/安装:解压软件包后执行insta ...