洛谷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 ,别的没什么大 ...
随机推荐
- 在docker容器下利用数据卷实现在删除了mysql容器或者镜像的情况下恢复数据
当把mysql容器销毁,在新建一个容器,进行之前的数据恢复. 因为之前建立了数据卷,那么现在就可以利用这个数据卷进行数据恢复. 使用docker volume create volume_name命令 ...
- redis 模拟jedis 操作string类型数据
一.思路分析 redis数据传输遵循resp协议,只需要按照resp协议并通过socket传递数据到redis服务器即可 resp数据格式: 二.具体实现 package com.ahd.jedis; ...
- nodejs express 上传文件自定义文件名和上传路径
1.客户端 <form action="http://localhost:3000/profile" method="post" enctype=&quo ...
- js 一些小技巧
Javascript 中的 绑定事件 on $(document).on("事件","元素","方法"): Js 定时方法 1.setTim ...
- QWidget 设置背景图片
QWidget 设置背景图片办法: 利用 QPaltette QPixmap pixmap("back.png"); QPalette palette; palette.setBr ...
- python grobal 的使用方法
写一个功能,运行报错,name 'number' is used prior to global declaration ,查资料梳理一下 因为这个函数需要调用多次,第一次调用的时候,走if语句,后面 ...
- Ubuntu16.04下caffe CPU版的图片训练和测试
一 数据准备 二.转换为lmdb格式 1.首先,在examples下面创建一个myfile的文件夹,来用存放配置文件和脚本文件.然后编写一个脚本create_filelist.sh,用来生成train ...
- 解决在linux下安装centos自带的mysql后,出现navicat远程连接失败的问题
最近在学习关于数据库相关的东西,所以下午尝试在linux下自己搭建了myql,我的mysql是直接安装centos系统自带的,安装过程不再赘述 安装完成后,从linux后台登录也显示成功,但是就是从n ...
- 【HDU4276】The Ghost Blows Light
题目大意:给定一棵有根树,1 号节点为根节点,点有点权,边有边权,初始给定一个价值,每经过一条边都会减少该价值,每经过一个点都会增加相应的答案贡献值,求如何在给定价值的情况下最大化答案贡献,并要求最后 ...
- PHP连接mongodb的现代用法---使用Monogodb\Driver\Manager
目的:在php程序端查询文档相关集合存储情况 <?php /** * Created by PhpStorm. * User: Administrator * Date: 2018/11/29 ...