【AHOI2009】 维护序列 - 线段树
题目描述
老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成。 有长为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】 维护序列 - 线段树的更多相关文章
- BZOJ1798[Ahoi2009]维护序列——线段树
题目描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2 ...
- [P2023][AHOI2009]维护序列(线段树)
题目描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2)把数列中的一 ...
- [AHOI2009]维护序列 (线段树)
题目描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,-,aN .有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2)把数列中的一 ...
- 洛谷 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 ...
- BZOJ 1798 AHOI2009 Seq 维护序列 线段树
题目大意:维护一个序列,提供三种操作: 1.将区间中每个点的权值乘上一个数 2.将区间中每个点的权值加上一个数 3.求一段区间的和对p取模的值 2631的超^n级弱化版.写2631之前能够拿这个练练手 ...
- [BZOJ1798][AHOI2009]Seq维护序列 线段树
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1798 一眼看过去线段树,事实上就是线段树.对于乘和加的两个标记,我们可以规定一个顺序,比如 ...
- 洛谷 P2023 维护序列——线段树
先上一波题目 https://www.luogu.org/problem/P2023 复习了一波线段树 题目涉及的操作有区间加 区间乘以及区间求和 tips:线段树在传标记的时候 优先传乘法标记再传加 ...
- COGS.1272.[AHOI2009]行星序列(线段树 区间加、乘、求和)
题目链接 //注意取模! #include<cstdio> #include<cctype> using namespace std; const int N=1e5+5; i ...
- BZOJ_1798_[AHOI2009]维护序列_线段树
BZOJ_1798_[AHOI2009]维护序列_线段树 题意:老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: ( ...
随机推荐
- C++语法小记---经典问题之一(一个空类包含什么)
问题:一个空类包含什么 空的构造函数 拷贝构造函数(浅拷贝) 重载赋值操作符函数(浅拷贝) 析构函数 取址运算符 取址运算符const 注意 所有的这些默认函数,只有在代码中调用了才会生成,否则也不会 ...
- vue-watch : 深度监控的语法格式--检测数据的tabledata这个数组的变化
watch:{ tableData:{ handler(a,b){ this.tableData= a; console.log(a ,b) }, deep:true }, }
- Arrays.sort() ----- DualPivotQuicksort
Arrays.sort() ----- DualPivotQuicksort DualPivotQuicksort是Arrays.sort()对基本类型的排序算法,它不止使用了双轴快速排序,还使用了T ...
- 篮球30S定时器设计
一.设计介绍 本设计采用74LS192作为计数器,74LS192具有同步加减计数功能,可以通过引脚电平对它设置达到清零重置的目的,可以达到对计数器清零的功能,使用两片级联74LS192分别显示十位和个 ...
- Java 异常处理专题,从入门到精通
内置异常和Throwable核心方法 Java内置异常 可查异常(必须要在方法里面捕获或者抛出) ClassNoFoundException 应⽤程序试图加载类,找不到对应的类 IllegalAcce ...
- matplotlib柱状图、面积图、直方图、散点图、极坐标图、箱型图
一.柱状图 1.通过obj.plot() 柱状图用bar表示,可通过obj.plot(kind='bar')或者obj.plot.bar()生成:在柱状图中添加参数stacked=True,会形成堆叠 ...
- Myeclipse-10.7.1版本破解
自从上次写了IDEA2020版本破解方式,这次写一下Myeclipse10.7.1版本破解 下方链接是IDEA破解教程 点击即可跳转 Myeclipse下载地址这里我上传到了百度网盘 这里提取码 ...
- Django学习路13_创建用户登录,判断数据库中账号名密码是否正确
在 models.py 中设置数据库表的信息 from django.db import models # Create your models here. class User(models.Mod ...
- 自述:转职IT ,痛苦一阵子;不转职IT,痛苦一辈子(第一章)
作为一个从后期制作转职过来的Java工程师,我认为我是幸运的,虽然我的本科专业(影视后期)也是火爆行业,不愁工作,但我不后悔进入这个IT坑,毕竟转行,只痛苦一阵子,但是不转行,可能我会痛苦一辈子. 我 ...
- PHP 数据库 ODBC创建 ODBC 连接
PHP 数据库 ODBC ODBC 是一种应用程序编程接口(Application Programming Interface,API),使我们有能力连接到某个数据源(比如一个 MS Access 数 ...