题目描述

老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成。 有长为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. SQL 给某字段添加汉字却显示??

    错误展示: 解决方案: 1.在要修改的数据库上单击鼠标右键,并选择“属性”.   2.在弹出的数据库属性窗口中点击“选择页”中的“选项”.   3.将排序规则由默认的SQL_Latin1_Genera ...

  2. 拆招黑客!github代码库大牛们如何应对黑客攻击

    2019年05月,<个人电脑杂志>网站报道,GitHub(2018年被微软收购)代码库正遭到一名黑客的入侵(392个资源库受损,约1000名用户受到攻击,真实资料未知).据称,这名黑客先擦 ...

  3. spring oauth2+JWT后端自动刷新access_token

    这段时间在学习搭建基于spring boot的spring oauth2 和jwt整合. 说实话挺折腾的.使用jwt做用户鉴权,难点在于token的刷新和注销. 当然注销的难度更大,网上的一些方案也没 ...

  4. Django序列化组件Serializers详解

    本文主要系统性的讲解django rest framwork 序列化组件的使用,基本看完可以解决工作中序列化90%的问题,写作参考官方文档https://www.django-rest-framewo ...

  5. 搭建NFS Server

    搭建NFS Server Kubetrain K8S在线直播培训,内推机会 不满意可无条件退款 现在就去广告 #背景 Kubernetes 对 Pod 进行调度时,以当时集群中各节点的可用资源作为主要 ...

  6. phpcms视频模块实现列表页打开内容页直接播放视频

    摘自phpcms论坛 原链接地址:http://bbs.phpcms.cn/thread-557691-1-1.html 之前下载研究过“化蝶自在飞”开发的视频模型,发现功能不错,但唯一的缺憾是,我想 ...

  7. goroutine调度源码阅读笔记

    以下为本人阅读goroutine调度源码随手记的笔记,现在还是一个个知识点的形式,暂时还没整理,先发到这里,一点点更新:   1). runq [256]guintptr P 的runable队列最大 ...

  8. 使用types库修改函数

    import types class ppp: pass p = ppp()#p为ppp类实例对象 def run(self): print("run函数") r = types. ...

  9. 每日一道 LeetCode (2):整数反转

    题目:整数反转 题目来源:https://leetcode-cn.com/problems/reverse-integer 给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转. 示 ...

  10. php getimagesize 函数 - 获取图像信息

    getimagesize() 函数用于获取图像大小及相关信息,成功返回一个数组,失败则返回 FALSE 并产生一条 E_WARNING 级的错误信息. 语法格式:高佣联盟 www.cgewang.co ...