线段树模板,洛谷原题P3373
线段树区间乘、加,范围求和,QWQ
原题
#include <bits/stdc++.h>
#define PII pair <int, int>
#define int long long
#define DB double
namespace FastIO
{
inline int read(int MOD, int &ret){
char ch = getchar();int ngtv = 1;
if(MOD == 0) {while(ch < '0' || ch > '9'){if(ch == '-') ngtv = -1;ch = getchar();}while(ch >= '0' && ch <= '9'){ret = ret * 10 + (ch - '0');ch = getchar();}}
else {while(ch < '0' || ch > '9'){if(ch == '-') ngtv = -1;ch = getchar();}while(ch >= '0' && ch <= '9'){ret = (ret * 10 % MOD + (ch - '0') % MOD) % MOD;ch = getchar();} }
return ret * ngtv;}
inline char cread(char &ch){while(ch == ' ' || ch == '\n' || ch == '\r' || ch == 0) ch = getchar();ch = getchar();return ch;}
}
using namespace FastIO;
using namespace std;
const int N = 4e5 + 10, M = 1e5 + 10;
int A[M], mod, n, q;
int opt, x, y, k;
struct Node
{
int sum, tag1, tag2;
// sum:区间和;tag1子节点未加的值;tag2:子节点未乘的值
int left, right;
// 左右节点(sum的范围)
}Tree[N];
void init_tree(int x, int left, int right)
{
Tree[x].left = left;
Tree[x].right = right;
if(left == right)
{
Tree[x].sum = A[left];
return ;
}
Tree[x].tag1 = 0;
Tree[x].tag2 = 1;
int mid = (left + right) >> 1;
init_tree(x * 2, left, mid);
init_tree(x * 2 + 1, mid + 1, right);
Tree[x].sum = (Tree[x * 2].sum + Tree[x * 2 + 1].sum) % mod;
}
void pushdown(int x)
{
int l = Tree[x].left, r = Tree[x].right;
int m = (l + r) >> 1;
Tree[x * 2].sum = (Tree[x * 2].sum * Tree[x].tag2 + (m - l + 1) * Tree[x].tag1) % mod;
Tree[x * 2 + 1].sum = (Tree[x * 2 + 1].sum * Tree[x].tag2 + (r - m) * Tree[x].tag1) % mod;
Tree[x * 2].tag1 = (Tree[x * 2].tag1 * Tree[x].tag2 + Tree[x].tag1) % mod;
Tree[x * 2 + 1].tag1 = (Tree[x * 2 + 1].tag1 * Tree[x].tag2 + Tree[x].tag1) % mod;
Tree[x * 2].tag2 = (Tree[x].tag2 * Tree[x * 2].tag2) % mod;
Tree[x * 2 + 1].tag2 = (Tree[x].tag2 * Tree[x * 2 + 1].tag2) % mod;
Tree[x].tag1 = 0;
Tree[x].tag2 = 1;
}
void add(int x, int l, int r, int ad)
{
if(l > Tree[x].right || Tree[x].left > r)
return ;
if(l <= Tree[x].left && Tree[x].right <= r)
{
Tree[x].tag1 = (Tree[x].tag1 + ad) % mod;
Tree[x].sum = (Tree[x].sum + (Tree[x].right - Tree[x].left + 1) * ad % mod) % mod;
return ;
}
pushdown(x);
add(x * 2, l , r, ad);
add(x * 2 + 1, l, r, ad);
Tree[x].sum = (Tree[x * 2].sum + Tree[x * 2 + 1].sum) % mod;
}
void ride(int x, int l, int r, int rid)
{
if(l > Tree[x].right || Tree[x].left > r)
return ;
if(l <= Tree[x].left && Tree[x].right <= r)
{
Tree[x].sum = (Tree[x].sum * rid) % mod;
Tree[x].tag1 = (Tree[x].tag1 * rid) % mod;
Tree[x].tag2 = (Tree[x].tag2 * rid) % mod;
return ;
}
pushdown(x);
ride(x * 2, l, r, rid);
ride(x * 2 + 1, l, r, rid);
Tree[x].sum = (Tree[x * 2].sum + Tree[x * 2 + 1].sum) % mod;
}
int sum(int x, int l, int r)
{
if(l > Tree[x].right || Tree[x].left > r)
return 0;
if(l <= Tree[x].left && Tree[x].right <= r)
return Tree[x].sum;
pushdown(x);
return (sum(x * 2, l, r) + sum(x * 2 + 1, l, r)) % mod;
}
signed main()
{
read(0, n), read(0, q), read(0, mod);
for(int i = 1; i <= n; i ++ )
read(0, A[i]);
init_tree(1, 1, n);
// 创建一个线段树 √
for(; q; q -- )
{
scanf("%d", &opt);
if(opt == 1)
{
scanf("%d%d%d", &x, &y, &k);
ride(1, x, y, k);
}
if(opt == 2)
{
scanf("%d%d%d", &x, &y, &k);
add(1, x, y, k);
}
if(opt == 3)
{
scanf("%d%d", &x, &y);
k = sum(1, x, y);
printf("%lld\n", k);
}
}
return 0;
}
线段树模板,洛谷原题P3373的更多相关文章
- AC日记——【模板】线段树 1 洛谷 P3372
题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.求出某区间每一个数的和 输入输出格式 输入格式: 第一行包含两个整数N.M,分别表示该数列数字的个数和操作的总个 ...
- AC日记——【模板】线段树 2 洛谷 P3373
P3373 [模板]线段树 2387通过1.8K提交标签难度 提高+/省选- 提交 讨论 题解 最新讨论 更多讨论 2333最后三个点卡常数.迷之RE感觉这题很迷啊好像一共三组测试数据.友情提示:开l ...
- 【线段树】洛谷 P3372 【模板】线段树 1
动态开结点线段树板子. #include<cstdio> using namespace std; typedef long long ll; ll sumv[400005],delta[ ...
- P3372 【模板】线段树 1 洛谷
https://www.luogu.org/problem/show?pid=3372 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.求出某区间每一个数的和 ...
- 线段树【洛谷P2894】 [USACO08FEB]酒店Hotel
P2894 [USACO08FEB]酒店Hotel 参考样例,第一行输入n,m ,n代表有n个房间,编号为1---n,开始都为空房,m表示以下有m行操作,以下 每行先输入一个数 i ,表示一种操作: ...
- [虚树模板] 洛谷P2495 消耗战
题意:给定树上k个点,求切断这些点到根路径的最小代价.∑k <= 5e5 解:虚树. 构建虚树大概是这样的:设加入点与栈顶的lca为y,比较y和栈中第二个元素的DFS序大小关系. 代码如下: i ...
- 洛谷P3372线段树模板1——线段树
题目:https://www.luogu.org/problemnew/show/P3372 线段树模板. 代码如下: #include<iostream> #include<cst ...
- [AHOI 2009] 维护序列(线段树模板题)
1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec Memory Limit: 64 MB Description 老师交给小可可一个维护数列的任务,现在小 ...
- hdu1823(二维线段树模板题)
hdu1823 题意 单点更新,求二维区间最值. 分析 二维线段树模板题. 二维线段树实际上就是树套树,即每个结点都要再建一颗线段树,维护对应的信息. 一般一维线段树是切割某一可变区间直到满足所要查询 ...
- [POJ2104] 区间第k大数 [区间第k大数,可持久化线段树模板题]
可持久化线段树模板题. #include <iostream> #include <algorithm> #include <cstdio> #include &l ...
随机推荐
- Linux ls 查看目录结构与文档信息
摘要:Linux ls命令用于列出目标目录中所有的子目录和文件,发掘并掌握ls命令及其参数设置可以驾轻就熟地管理文件,随心所欲地浏览并确定所在的位置! ls命令介绍 今天,楼兰胡杨继续跟各位猿友一 ...
- MySQL Explain查看执行计划详解
目录 前言 EXPLAIN 中的列 id 和select_type table type possible_keys key 和 key_len ref 和 rows Extra 小结 Referen ...
- Matlab使用yalmip与cplex12.10
本文同步发布于我的网站 软件版本 MATLAB R2023b yalmip 2021-03-31 CPLEX 12.10 不求新,但求适配.此版本组合经过我在两台电脑上成功安装 下载链接 链接:htt ...
- HarmonyOS运动开发:精准估算室内运动的距离、速度与步幅
前言 在室内运动场景中,由于缺乏 GPS 信号,传统的基于卫星定位的运动数据追踪方法无法使用.因此,如何准确估算室内运动的距离.速度和步幅,成为了运动应用开发中的一个重要挑战.本文将结合鸿蒙(Harm ...
- HNU FPGA课设项目上手指南
1.介绍 本文章旨在帮助HNU的同学更优雅的完成数电的FPGA课设(使用DE2-115),文章将涉及完成FPGA项目需要掌握的知识,资源分享以及一些关于完成项目的经验指导.大家快快搬好小板凳,准备发车 ...
- 「Note」字符串方向 - 自动机相关
1. AC 自动机 ACAM 1.1. 简介 AC 自动机用于解决多模式串匹配问题,例如求多个模式串在文本串中的出现次数.显著地,它的应用实际上非常广泛. 借助 KMP 的思想,我们对 Trie 树上 ...
- 解密prompt系列55.Agent Memory的工程实现 - Mem0 & LlamaIndex
记忆存储是构建智能个性化.越用越懂你的Agent的核心挑战.上期我们探讨了模型方案实现长记忆存储,本期将聚焦工程实现层面. What:记忆内容(手动管理 vs 自动识别) How:记忆处理(压缩/抽取 ...
- 肝了一个月整理了这份Java学习路线导图
很多人都在问应该怎么样学习java的知识点,java有哪些知识点?最近准备面试了,java知识点太多了又不知道如何开始复习?java的知识点太多太多,学完了又忘了.所以我们可以为每个知识点都整理成一份 ...
- Spring中的一些注解
@SuppressWarnings("all") 隐藏一些无意义的报错提示 ** @ConfigurationProperties(prefix = "spring.da ...
- 如何在FastAPI中巧妙玩转数据脱敏,让敏感信息安全无忧?
扫描二维码 关注或者微信搜一搜:编程智域 前端至全栈交流与成长 发现1000+提升效率与开发的AI工具和实用程序:https://tools.cmdragon.cn/ 一.Pydantic模型敏感字段 ...