原理倒是非常简单。设原数为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. 初识glib(1)

    最近搞DLNA,发现download的源码有许多glib库的使用.于是在Ubuntu中安装了glib库,以及简单测试了一些glib库函数,以此增加对glib的了解. 概述:glib库是Linux平台下 ...

  2. mysql语句:SET NAMES UTF8

    一直以来只知道mysql_query("SET NAMES UTF8");是设定数据库编码的,但是一直不清楚“SET NAMES UTF8”是什么. 直到今天才知道 SET NAM ...

  3. HDU 2601An easy problem-素数的运用,暴力求解

    id=17433" target="_blank" style="color:blue; text-decoration:none">An ea ...

  4. hdu4921 Map

    给最多10条链.每条链长度最大1000,链上每点有权值,每条链上按顺序,第i个点属于level[i]. 链上后一个点能够选的前提是前面的点都选了. 选择了一些点能够得到的分数是两部分加起来:1.所有点 ...

  5. ExtJs学习笔记(1)---ExtJs安装及其使用

    从官网下载了ExtJs的3.2版本号的SDK,包括了代码依赖的具体说明.文档.范例和其它文件.当中,adapter和resources文件是Ext正常执行所必须的,其它的仅在开发过程中使用到. Ada ...

  6. 程序编写安全代码——sendto和recvfrom的大坑

    近日帮一个兄弟查代码问题,再处理完一系列问题以后,发现程序某些时候工作还是不正常,甚至会崩溃.因为环境所限,不能使用gdb,所以我只能review他的代码.最终发现原来是sendto和recvfrom ...

  7. Android app身体质量指数(BMI)

    针对中国人的标准身高体重来測算,提示您身体的健康状况. 提示您是否应该锻炼.节食或者补充营养等.第一时间知道您的健康状况. 下载地址:http://android.myapp.com/myapp/de ...

  8. sanic官方文档解析之静态文件和版本

    1,静态文件 就向图片文件一样,静态文件和指导性的文件,当通过Sanic服务端用app.static()方法注册的时候,这种方法采用端点url和文件名称获得.这样的文件的指定,将会通过指定的端点访问. ...

  9. js实现域名判断后跳转到指定网址

    js实现域名判断后跳转到指定网址,也适用于同一虚拟空间放多个网站: <script>       try           {               if(self.locatio ...

  10. CodeForces-607B:Zuma (基础区间DP)

    Genos recently installed the game Zuma on his phone. In Zuma there exists a line of n gemstones, the ...