题目描述

老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成。 有长为N的数列,不妨设为a1,a2,…,aN 。有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2)把数列中的一段数全部加一个值; (3)询问数列中的一段数的和,由于答案可能很大,你只需输出这个数模P的值。

思路

线段树,打个乘法lazy标记即可

#include <cstdio>
const int maxn = 100000 + 10;
struct Seg { long long l,r,sum,add,mul; } tree[maxn*4];
long long p;
long long n,m;
inline void pushup(long long root) { tree[root].sum = tree[root<<1].sum+tree[root<<1|1].sum; tree[root].sum %= p; }
inline void BuildTree(long long l,long long r,long long root) {
tree[root].l = l;
tree[root].r = r;
tree[root].mul = 1;
if (l == r) {
scanf("%lld",&tree[root].sum);
tree[root].sum %= p;
return;
}
long long mid = l+r>>1;
BuildTree(l,mid,root<<1);
BuildTree(mid+1,r,root<<1|1);
pushup(root);
}
inline void pushdown(long long root) {
if (tree[root].mul != 1) {
tree[root<<1].mul = tree[root<<1].mul*tree[root].mul%p;
tree[root<<1|1].mul = tree[root<<1|1].mul*tree[root].mul%p;
tree[root<<1].add = tree[root<<1].add*tree[root].mul%p;
tree[root<<1|1].add = tree[root<<1|1].add*tree[root].mul%p;
tree[root<<1].sum = tree[root<<1].sum*tree[root].mul%p;
tree[root<<1|1].sum = tree[root<<1|1].sum*tree[root].mul%p;
tree[root].mul = 1;
}
if (tree[root].add != 0) {
tree[root<<1].add = (tree[root<<1].add+tree[root].add)%p;
tree[root<<1|1].add = (tree[root<<1|1].add+tree[root].add)%p;
tree[root<<1].sum = (tree[root<<1].sum+tree[root].add*(tree[root<<1].r-tree[root<<1].l+1))%p;
tree[root<<1|1].sum = (tree[root<<1|1].sum+tree[root].add*(tree[root<<1|1].r-tree[root<<1|1].l+1))%p;
tree[root].add = 0;
}
}
inline void UpdateAdd(long long ql,long long qr,long long l,long long r,long long root,long long x) {
if (ql > r || qr < l) return;
if (ql <= l && qr >= r) {
tree[root].add = (tree[root].add+x)%p;
tree[root].sum = (tree[root].sum+x*(r-l+1))%p;
return;
}
pushdown(root);
long long mid = l+r>>1;
UpdateAdd(ql,qr,l,mid,root<<1,x);
UpdateAdd(ql,qr,mid+1,r,root<<1|1,x);
pushup(root);
}
inline void UpdateMul(long long ql,long long qr,long long l,long long r,long long root,long long x) {
if (ql > r || qr < l) return;
if (ql <= l && qr >= r) {
tree[root].add = tree[root].add*x%p;
tree[root].mul = tree[root].mul*x%p;
tree[root].sum = tree[root].sum*x%p;
return;
}
pushdown(root);
long long mid = l+r>>1;
UpdateMul(ql,qr,l,mid,root<<1,x);
UpdateMul(ql,qr,mid+1,r,root<<1|1,x);
pushup(root);
}
inline long long Query(long long ql,long long qr,long long l,long long r,long long root) {
if (ql > r || qr < l) return 0;
if (ql <= l && qr >= r) return tree[root].sum;
pushdown(root);
long long mid = l+r>>1;
return (Query(ql,qr,l,mid,root<<1)+Query(ql,qr,mid+1,r,root<<1|1))%p;
}
int main() {
scanf("%lld%lld",&n,&p);
BuildTree(1,n,1);
scanf("%lld",&m);
while (m--) {
long long val;
long long op,l,r;
scanf("%lld%lld%lld",&op,&l,&r);
if (op == 1) {
scanf("%lld",&val);
UpdateMul(l,r,1,n,1,val);
} else if (op == 2) {
scanf("%lld",&val);
UpdateAdd(l,r,1,n,1,val);
} else printf("%lld\n",Query(l,r,1,n,1));
}
return 0;
}

【AHOI2009】 维护序列 - 线段树的更多相关文章

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

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

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

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

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

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

  4. 洛谷 P2023 [AHOI2009]维护序列 || 线段树加法和乘法运算

    原理倒是非常简单.设原数为x,加法的lazytag为b,乘法的lazytag为a,操作数为c,那么原式为ax+b,乘上c后(ax+b)c=(ac)*x+b*c,加上c后(ax+b)+c=ax+(b+c ...

  5. BZOJ 1798 AHOI2009 Seq 维护序列 线段树

    题目大意:维护一个序列,提供三种操作: 1.将区间中每个点的权值乘上一个数 2.将区间中每个点的权值加上一个数 3.求一段区间的和对p取模的值 2631的超^n级弱化版.写2631之前能够拿这个练练手 ...

  6. [BZOJ1798][AHOI2009]Seq维护序列 线段树

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1798 一眼看过去线段树,事实上就是线段树.对于乘和加的两个标记,我们可以规定一个顺序,比如 ...

  7. 洛谷 P2023 维护序列——线段树

    先上一波题目 https://www.luogu.org/problem/P2023 复习了一波线段树 题目涉及的操作有区间加 区间乘以及区间求和 tips:线段树在传标记的时候 优先传乘法标记再传加 ...

  8. COGS.1272.[AHOI2009]行星序列(线段树 区间加、乘、求和)

    题目链接 //注意取模! #include<cstdio> #include<cctype> using namespace std; const int N=1e5+5; i ...

  9. BZOJ_1798_[AHOI2009]维护序列_线段树

    BZOJ_1798_[AHOI2009]维护序列_线段树 题意:老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: ( ...

随机推荐

  1. 在 Docker 搭建 Maven 私有库

    在 Docker 搭建 Maven 私有库 小引 If you are developing software without a repository manager you are likely ...

  2. Mybatis核心模块简介

    Configuration 主要字段 Environment:配置DataSource和TransactionFactory ObjectFactory:bean工厂 MapperRegistry:M ...

  3. el-table 操作列(编辑or删除) 获取本行相关数据

    简单说明:开发的时候,经常会遇到表格后面跟着操作列,一般都是编辑或者删除,那么 就需要获取到 本行数据相关的id或者其他附属信息.ok,下边放代码 //vue el-table的部分代码 <el ...

  4. 从Python开始学编程|PDF百度网盘免费下载|Python新手入门

    百度网盘免费下载:从Python开始学编程|附PDF免费下载 提取码:7nkf 豆瓣评分: 本书封面: 读者评论: 内容简介  · · · · · · 改编自Vamei博客的<Python快速教 ...

  5. BUUCTF-web ikun(Python 反序列化)

    正如本题所说,脑洞有点大.考点还很多,不过最核心的还是python的pickle反序列化漏洞 题目中暗示了要6级号,找了很多页都没看到,于是写了脚本 在第180页有6级号,但是价格出奇的高,明显买不起 ...

  6. 篮球30S定时器设计

    一.设计介绍 本设计采用74LS192作为计数器,74LS192具有同步加减计数功能,可以通过引脚电平对它设置达到清零重置的目的,可以达到对计数器清零的功能,使用两片级联74LS192分别显示十位和个 ...

  7. MyBatis Plus 导入IdType失败

    import com.baomidou.mybatisplus.annotation.IdType; 修正Entity模板IdType引入包名到com.baomidou.mybatisplus.enu ...

  8. 2016A06寒假作业 全排列

    又是一个全排列哈, 注意注意,这个题不是十三个数字都需要,但原理是一样的 一开始把for的边界写错了(每次其实应该从k开始,还没看出来orz) #include <iostream> #i ...

  9. Python异常及异常处理

    Python异常及异常处理: 当程序运行时,发生的错误称为异常 例: 0 不能作为除数:ZeroDivisionError 变量未定义:NameError 不同类型进行相加:TypeError 异常处 ...

  10. TCP 客户端

    """ 创建客户端 绑定服务器ip地址和端口号(端口号是整型) 与服务器建立连接 发送给服务器要发送的数据(转码) 接收服务器返回的数据 关闭客户端 "&quo ...