洛谷P2023 [AHOI2009]维护序列(线段树区间更新,区间查询)
区间修改
当我们要修改一个区间时,要保证 \(ax+b\) 的形式,即先乘后加的形式。当将区间乘以一个数 \(k\) 时,原来的区间和为 \(ax+b\) ,乘以 \(k\) 得 \(k(ax+b)=kax+kb\) 。
区间加一个数更加简单,原来的区间和为 \(ax+b\) ,加上一个 \(k\) 为 \(ax+b+k\) ,合并 \(b\) ,\(k\) 得 \(ax+(b+k)\) 。
标记下传
\]
#include<bits/stdc++.h>
using namespace std;
#define lson l, mid, root << 1
#define rson mid + 1, r, root << 1 | 1
const int maxn = 100005;
long long tree[maxn << 2];
int n, p, q;
struct L{
long long mul, add;
}label[maxn << 2];
inline void pushUp(int root)
{
tree[root] = (tree[root << 1] + tree[root << 1 | 1]) % p;
}
inline void pushDown(int root, int len)
{
if(label[root].add == 0 && label[root].mul == 1) return;
else{
tree[root << 1] = (label[root].mul * tree[root << 1] + label[root].add * (len - (len >> 1))) % p;/***长度划分***/
tree[root << 1 | 1] = (label[root].mul * tree[root << 1 | 1] + label[root].add * (len >> 1)) % p;
label[root << 1].add = (label[root].mul * label[root << 1].add + label[root].add) % p;
label[root << 1 | 1].add = (label[root].mul * label[root << 1 | 1].add + label[root].add) % p;
label[root << 1].mul = (label[root << 1].mul * label[root].mul) % p;
label[root << 1 | 1].mul = (label[root << 1 | 1].mul * label[root].mul) % p;
label[root].add = 0; label[root].mul = 1;
}
}
void build(int l, int r, int root)
{
label[root].add = 0; label[root].mul = 1;
if(l == r){
scanf("%lld", &tree[root]); return;
}
int mid = (l + r) >> 1;
build(lson); build(rson);
pushUp(root);
}
void update(int l, int r, int root, int L, int R, int tag, int c)
{
if(L == l && R == r){
if(tag == 1){
tree[root] = tree[root] * c % p;
label[root].add = label[root].add * c % p;
label[root].mul = label[root].mul * c % p;
}else{
tree[root] = (tree[root] + c * (r - l + 1)) % p;
label[root].add = (label[root].add + c) % p;
}
return;
}
pushDown(root, r - l + 1);
int mid = (l + r) >> 1;
if(L >= mid + 1) update(rson, L, R, tag, c);
else if(R <= mid) update(lson, L, R, tag, c);
else{
update(lson, L, mid, tag, c); update(rson, mid + 1, R, tag, c);
}
pushUp(root);
}
long long query(int l, int r, int root, int L, int R)
{
if(L == l && R == r){
return tree[root] % p;
}
pushDown(root, r - l + 1);
int mid = (l + r) >> 1;
if(L >= mid + 1) return (query(rson, L, R) % p);
else if(R <= mid) return (query(lson, L, R) % p);
else{
return ((query(lson, L, mid) + query(rson, mid + 1, R)) % p);
}
}
int main()
{
scanf("%d%d", &n, &p);
build(1, n, 1);
scanf("%d", &q);
for(int cas = 1; cas <= q; cas++){
int tag, t, g, c;
scanf("%d", &tag);
if(tag == 1){
scanf("%d%d%d", &t, &g, &c);
update(1, n, 1, t, g, 1, c);
}
else if(tag == 2){
scanf("%d%d%d", &t, &g, &c);
update(1, n, 1, t, g, 2, c);
}
else{
scanf("%d%d", &t, &g);
printf("%lld\n", query(1, n, 1, t, g) % p);
}
}
return 0;
}
洛谷P2023 [AHOI2009]维护序列(线段树区间更新,区间查询)的更多相关文章
- 洛谷 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 ...
- 洛谷 P2023 [AHOI2009]维护序列 题解
P2023 [AHOI2009]维护序列 题目描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,-,aN .有如下三种操作形式: (1)把数列中 ...
- 洛谷 P2023 [AHOI2009]维护序列
P2023 [AHOI2009]维护序列 题目描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: (1)把数列中 ...
- 【题解】洛谷P2023 [AHOI2009] 维护序列(线段树)
洛谷P2023:https://www.luogu.org/problemnew/show/P2023 思路 需要2个Lazy-Tag 一个表示加的 一个表示乘的 需要先计算乘法 再计算加法 来自你谷 ...
- [洛谷P2023] [AHOI2009]维护序列
洛谷题目链接:[AHOI2009]维护序列 题目描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,-,aN .有如下三种操作形式: (1)把数列 ...
- [P2023][AHOI2009]维护序列(线段树)
题目描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2)把数列中的一 ...
- 洛谷 2023 [AHOI2009]维护序列
洛谷 2023 [AHOI2009]维护序列 洛谷原题传送门 这个题也是一道经典的线段树模版(其实洛谷的模版二改一下输入顺序就能AC),其中包括区间乘法修改.区间加法修改.区间查询三个操作. 线段树的 ...
- POJ.2528 Mayor's posters (线段树 区间更新 区间查询 离散化)
POJ.2528 Mayor's posters (线段树 区间更新 区间查询 离散化) 题意分析 贴海报,新的海报能覆盖在旧的海报上面,最后贴完了,求问能看见几张海报. 最多有10000张海报,海报 ...
- POJ.3468 A Simple Problem with Integers(线段树 区间更新 区间查询)
POJ.3468 A Simple Problem with Integers(线段树 区间更新 区间查询) 题意分析 注意一下懒惰标记,数据部分和更新时的数字都要是long long ,别的没什么大 ...
随机推荐
- PropertyUtilsBean 将bean转成map
public static Map<String,String> beanToMap(Object bean) { Map<String,String> params =Map ...
- docker数据卷挂载
docker数据卷挂载笔记 我们的服务运行时必不可少的会产生一些日志,或是我们需要把容器内的数据进行备份,甚至多个容器之间进行数据共享,这必然涉及容器的数据管理操作. 容器中管理数据主要有两种方式: ...
- java中的集合类详情解析以及集合和数组的区别
数组和链表 数组:所谓数组就是相同数据类型的元素按照一定顺序排列的集合. 它的存储区间是连续的,占用内存严重,所以空间复杂度很大,为o(n),但是数组的二分查找时间复杂度很小为o(1). 特点是大小固 ...
- vue-注册全局过滤器
import Vue from 'vue'; import dayjs from 'dayjs'; const filters = { formatDate(date, format = 'YYYY- ...
- Spring Boot整合Spring Security总结
一.创建Spring Boot项目 引入Thymeleaf和Web模块以及Spring Security模块方便进行测试,先在pom文件中将 spring-boot-starter-security ...
- python中reload(sys)作用
python在安装时,默认的编码是ascii,当程序中出现非ascii编码时,python的处理常常会报错UnicodeDecodeError: 'ascii' codec can't decode ...
- 最简单的Android项目(添加jar文件)
如果项目需要引用第三方jar文件,需要对编译命令做一些改动. 首先在项目根目录创建libs目录,将需要的jar文件拷贝到里面. 编译过程中有两步需要改动. 编译java源文件时,需要添加class p ...
- IDL_MCTK(MODIS Conversion Toolkit)
1.CONVERT_MODIS_DATA CONVERT_MODIS_DATA [,IN_FILE= | | }] [,GEOLOC_FILE= | | }] [,CALIB_METHOD={ | | ...
- 分布式配置中心(Spring Cloud Config) (问题解答)
转载:https://blog.csdn.net/forezp/article/details/70037291 1.foo是博主随意写的,实际是没有对应的文件.如果真有文件,返回的json在会有so ...
- iOS 自定义NavigationBar右侧按钮rightBarButtonItem
自定义右侧的一个按钮 UIBarButtonItem *myButton = [[UIBarButtonItem alloc] initWithTitle:@"主页" style: ...