原理倒是非常简单。设原数为x,加法的lazytag为b,乘法的lazytag为a,操作数为c,那么原式为ax+b,乘上c后(ax+b)c=(ac)*x+b*c,加上c后(ax+b)+c=ax+(b+c),因此加法时只需要更新加法的lazytag,乘法的时候就需要同时乘乘法和加法的lazytag。(乘法时的操作曾经搞错)

有些细节却很难受啊...比如很容易忘记加取模(一般都是程序打完了之后再补上,但是这个程序要补的地方太多,容易漏,要小心),把乘法的lazytag初始化为1出错,很容易少几句话...

 //以下代码中:加important标记的是曾经缺少的,注释掉的是曾经多的
#include<cstdio>
#include<cstring>
#define lc (num<<1)
#define rc (num<<1|1)
#define mid ((l+r)>>1)
typedef long long LL;
LL a[];
LL tree[],laz[],laz2[];
LL L,R,x,n,m,md;
void build(LL l,LL r,LL num)
{
laz2[num]=;//important
if(l==r)
{
tree[num]=a[l]%md;
return;
}
build(l,mid,lc);
build(mid+,r,rc);
tree[num]=(tree[lc]+tree[rc])%md;
}
void pushdown(LL l,LL r,LL num)
{
if(laz2[num]!=)
{
laz2[lc]=(laz2[lc]*laz2[num])%md;
laz2[rc]=(laz2[rc]*laz2[num])%md;
/*important*/
laz[lc]=(laz[lc]*laz2[num])%md;
laz[rc]=(laz[rc]*laz2[num])%md;
tree[lc]=(tree[lc]*laz2[num])%md;
tree[rc]=(tree[rc]*laz2[num])%md;
/*-important*/
/*
tree[lc]=(tree[lc]+(mid-l+1)*laz2[num])%md;
tree[rc]=(tree[rc]+(r-mid)*laz2[num])%md;
*/
laz2[num]=;
}
if(laz[num])
{
laz[lc]=(laz[lc]+laz[num])%md;
laz[rc]=(laz[rc]+laz[num])%md;
tree[lc]=(tree[lc]+(mid-l+)*laz[num]%md)%md;
tree[rc]=(tree[rc]+(r-mid)*laz[num]%md)%md;
laz[num]=;
}
}
void update(LL l,LL r,LL num)
{
if(L<=l&&r<=R)
{
tree[num]=(tree[num]+(r-l+)*x)%md;
laz[num]=(laz[num]+x)%md;
return;
}
pushdown(l,r,num);
if(L<=mid) update(l,mid,lc);
if(mid<R) update(mid+,r,rc);//if(mid+1<=R)//等价
/*important*/tree[num]=(tree[lc]+tree[rc])%md;
}
void update2(LL l,LL r,LL num)
{
if(L<=l&&r<=R)
{
tree[num]=(tree[num]*x)%md;
/*importaant*/laz[num]=(laz[num]*x)%md;/*important*/
laz2[num]=(laz2[num]*x)%md;
return;
}
pushdown(l,r,num);
if(L<=mid) update2(l,mid,lc);
if(mid<R) update2(mid+,r,rc);//if(mid+1<=R)//等价
/*important*/tree[num]=(tree[lc]+tree[rc])%md;
}
LL query(LL l,LL r,LL num)
{
if(L<=l&&r<=R) return tree[num];
pushdown(l,r,num);
LL ans=;
if(L<=mid) ans=(ans+query(l,mid,lc))%md;
if(mid<R) ans=(ans+query(mid+,r,rc))%md;
return ans;
}
int main()
{
LL i,t;
scanf("%lld%lld%lld",&n,&m,&md);
for(i=;i<=n;i++)
scanf("%lld",&a[i]);//不应该将laz2[]=1写在此处important
build(,n,);
for(i=;i<=m;i++)
{
scanf("%lld",&t);
if(t==)
{
scanf("%lld%lld%lld",&L,&R,&x);
update(,n,);
}
else if(t==)
{
scanf("%lld%lld",&L,&R);
printf("%lld\n",query(,n,)%md);
}
else
{
scanf("%lld%lld%lld",&L,&R,&x);
update2(,n,);
}
}
return ;
}

洛谷 P2023 [AHOI2009]维护序列 || 线段树加法和乘法运算的更多相关文章

  1. 洛谷P2023 [AHOI2009]维护序列(线段树区间更新,区间查询)

    洛谷P2023 [AHOI2009]维护序列 区间修改 当我们要修改一个区间时,要保证 \(ax+b\) 的形式,即先乘后加的形式.当将区间乘以一个数 \(k\) 时,原来的区间和为 \(ax+b\) ...

  2. 洛谷 P2023 [AHOI2009]维护序列 题解

    P2023 [AHOI2009]维护序列 题目描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,-,aN .有如下三种操作形式: (1)把数列中 ...

  3. 洛谷 P2023 [AHOI2009]维护序列

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

  4. 【题解】洛谷P2023 [AHOI2009] 维护序列(线段树)

    洛谷P2023:https://www.luogu.org/problemnew/show/P2023 思路 需要2个Lazy-Tag 一个表示加的 一个表示乘的 需要先计算乘法 再计算加法 来自你谷 ...

  5. [洛谷P2023] [AHOI2009]维护序列

    洛谷题目链接:[AHOI2009]维护序列 题目描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,-,aN .有如下三种操作形式: (1)把数列 ...

  6. [P2023][AHOI2009]维护序列(线段树)

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

  7. 洛谷 2023 [AHOI2009]维护序列

    洛谷 2023 [AHOI2009]维护序列 洛谷原题传送门 这个题也是一道经典的线段树模版(其实洛谷的模版二改一下输入顺序就能AC),其中包括区间乘法修改.区间加法修改.区间查询三个操作. 线段树的 ...

  8. BZOJ1798[Ahoi2009]维护序列——线段树

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

  9. [AHOI2009]维护序列 (线段树)

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

随机推荐

  1. MapReduce简述、工作流程及新旧API对照

    什么是MapReduce? 你想数出一摞牌中有多少张黑桃.直观方式是一张一张检查而且数出有多少张是黑桃. MapReduce方法则是: 1. 给在座的全部玩家中分配这摞牌. 2. 让每一个玩家数自己手 ...

  2. Chrome浏览器V43版本号不支持silverlight 5.0的解决的方法

    场景: 浏览器:chrome V43 插件:silverlight 5.0 操作系统:xp 问题: 自己开发silverlight站点在IE7和firefox中能正常打开,但在chrome中打开失败. ...

  3. Tomcat 安装与配置规范

    Tomcat 安装 演示版本:8.5.32 安装版 JDK推荐版本:jdk1.8 下载地址:https://tomcat.apache.org/download-80.cgi 安装教程 注意:tomc ...

  4. URAL 1731. Dill(数学啊 )

    题目链接:http://acm.timus.ru/problem.aspx?space=1&num=1731 1731. Dill Time limit: 0.5 second Memory ...

  5. date format记录

    各种日期格式定义,容易忘记,这里备注下: * 支持格式为 yyyy.MM.dd G 'at' hh:mm:ss z 如 '2002-1-1 AD at 22:10:59 PSD'<br> ...

  6. linux 一个超简单的makefile

    makefile 自动化变量:   $@ : 规则的目标文件名  例如:main:main.o test.o                    g++ -Wall -g  main.o test. ...

  7. uboot配置和编译过程详解【转】

    本文转载自:http://blog.csdn.net/czg13548930186/article/details/53434566 uboot主Makefile分析1 1.uboot version ...

  8. jsp重写url

    众所周知,使用java web编程出来的网站都是.jsp结尾的,而别人的网站都是以.html结尾的,那么这种效果是怎么实现的呢?就是这篇文章产生的原因,jsp重写url需要设计到第三方架包urlrew ...

  9. 使用cocoaPods加载框架的具体步骤:

    注意事项: 1.使用之前备份一下代码.因为pod更新很快,如果某个文件名有中文,pod install 一下.整个项目可能就要废掉了. 2.如果不把pod文件推动到远程服务器. 每一次用的时候在本地p ...

  10. 二维码解码器Zbar+VS2012开发环境配置

    Zbar条码解码器是一个开源的二维码(包括条形码)解码器,可以识别来至于视频流,图像文件.手持扫码器和视频设备(如摄像头)等二维码识别,支持EAN-13/UPC-A, UPC-E, EAN-8, Co ...