原理倒是非常简单。设原数为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. label 对齐

    <label for="username">用户名</label> <input type="text" id="use ...

  2. Python开发【2.1 面向对象】

    1.面向对象概述 类(Class): 用来描述具有相同的属性和方法的对象的集合.它定义了该集合中每个对象所共有的属性和方法.对象是类的实例. 类变量:类变量在整个实例化的对象中是公用的.类变量定义在类 ...

  3. 2016/07/05 zend optimizer

    Zend Optimizer是由PHP核心引擎“Zend” http://www.zend.com 创建者Zend技术公司所开的免费PHP优化软件.据Zend公司透露使用这个软件某些情况下至少可以提高 ...

  4. DRF框架

    1.RESTful规范 1.1 REST风格:表属性状态转移 1.1.1资源:在web中凡是有被引用的必要的都叫资源 1.1.2 URI:统一资源标识符    URI包含URL 1.1.3 URL:统 ...

  5. python day- 6 is 和 ==的区别 encode 和 decode

    1.is 和  == 的区别. == 是由来判断左右两边的内容是否相等. is 是用来判断内存地址是否相同. 引进 id (   )函数 小数据池: 对于字符串 ,数字 ,bool 值进行 id()计 ...

  6. BZOJ 1567: [JSOI2008]Blue Mary的战役地图 矩阵二维hash

    1567: [JSOI2008]Blue Mary的战役地图 Description Blue Mary最近迷上了玩Starcraft(星际争霸) 的RPG游戏.她正在设法寻找更多的战役地图以进一步提 ...

  7. hadoop yarn namenode datanoe 启动异常问题解决 分析日志

    cat logs/hadoop-root-datanode-hadoop1.log ********************************************************** ...

  8. java和jar命令

    IDEA打可运行jar http://bglmmz.iteye.com/blog/2058785 -jar参数运行应用时classpath的设置方法 你是否在使用java -jar参数运行打包好的ja ...

  9. Configuring Your EMS Server or EMS Console Server on Windows/Linux

    EMS Configuration Files RAD Studio provides the scripts to render the web-browser console, the EMS s ...

  10. SKU多维属性状态判断算法

    作者:周琪力,前端工程师,网络常用昵称「keelii」.在过去的4年里主要负责京东网站商品详情页的前端系统架构和开发,平时主要写 JavaScript 偶尔写点NodeJS,Python.琪力博客:  ...