原理倒是非常简单。设原数为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. Hibernate quick start

    Preface Working with both Object-Oriented software and Relational Databases can be cumbersome and ti ...

  2. C#令人迷惑的DateTime:世界标准时间还是本地时间?

    先来看一段代码: 复制内容到剪贴板程序代码 DateTime time = DateTime.Parse("2013-07-05 00:00:00");Console.WriteL ...

  3. hadoop mapred和mapreduce包

    mapred包是老的1.0的map reduce api mapreduce包是新的2.0的map reduce api

  4. using the flume-ng-sql-source plugin to push data from Mysql DB to Spark

    org.apache.flume.EventDeliveryException while running flume and sending data to spark · Issue #21 · ...

  5. mongodb的安装、配置、常见问题

    一.MongoDB下载 mongodb可以在官网找到下载链接,找到合适的版本进行下载.下载地址->https://www.mongodb.com/download-center?jmp=nav# ...

  6. 【转】【录教程必备】推荐几款屏幕录制工具(可录制GIF)

    我们经常会遇到一些场景,需要你向别人展示一些操作或是效果——例如告诉别人某某软件的配置步骤啊.刚设计出来网站的动画效果怎么样啊.某某电影里面的一个镜头多么经典啊.打得大快人心的NBA绝杀瞬间是怎么回事 ...

  7. 在docker里查看java进程

    先使用命令查看docker的运行进程 docker ps [root@localhost logs]# docker ps CONTAINER ID        IMAGE             ...

  8. java 简单贪吃蛇

    1. [代码]java 简单程序     跳至 [1] [全屏预览]package com.snake;import java.awt.*;import javax.swing.*;import ja ...

  9. Mysql语句示例

    Mysql语句示例 最常用 sql 语句总结 前言 Mysql 是数据库开发使用的主要平台之一.sql 的学习掌握与使用是数据库开发的基础,此处展示详细sql 语句的写法,及各种功能下的 sql 语句 ...

  10. Oracle:varchar2、nvarchar2 字段类型的区别

    一直对varchar2.nvarchar2 字段类型存储字符数不清楚,现测试如下: 创建TT测试表 测试脚本如下: insert into tt values('1111','1111');  --- ...