线段树模板,洛谷原题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 ...
随机推荐
- HashMap知识点梳理、常见面试题和源码分析
本博客是包括HashMap在内的相关知识点博文链接的入口,从介绍哈希表的基本概念开始,到HashMap的应用.实现原理和常见面试题,包括分析其源码,还包括相关知识点的延伸,例如HashSet等. ...
- Linux下搭建Kafka集群
摘要 Kafka 是一个分布式的基于push-subscribe的消息系统,它具备快速.可扩展.可持久化的特点.由 LinkedIn 开源,用作 LinkedIn 的活动流(Activity Stre ...
- Git镜像网站和Git网站提速方法
最近开始学习使用git,但是因为git是国外的网站,所以基本就是无法访问.如下图: 通过在网上查找资料,我发现了几个访问git的方法. 方法一.通过镜像网站 镜像网站一: https://github ...
- Java Solon v3.3.2 发布(可替换,美国博通公司的 Spring 方案)
Solon 框架! Solon 是新一代,Java 企业级应用开发框架.从零开始构建(No Java-EE),有灵活的接口规范与开放生态.采用商用友好的 Apache 2.0 开源协议,是" ...
- 在SpringCloud中的相关报错
在SpringCloud中使用REST服务时 使用前需要先在配置类中注入RestTemplate的Bean 然后再使用 自动装配即可 @Autowired private RestTemplate r ...
- ESP32-Arduino物联网工控(一)串口转TCP转发机项目简介
Arduino 在物联网上配合ESP32简直就是神器! 然后现在大老板说新设备用ESP32来帮助原本没有联网功能的STM32单片机来进行调试...... 实现需求: 1.指定命令拍照,协议HTTP,并 ...
- 深入理解 Taier:MR on Yarn 的实现原理
我们今天常说的大数据技术,它的理论基础来自于2003年 Google 发表的三篇论文,<The Google File System>.<MapReduce: Simplified ...
- ChatGPT学习之旅 (3) Prompt进阶用法
大家好,我是Edison. 上一篇:Hello Prompt 复习Prompt用法 还记得上一篇学到的黄金公式吗? 这里,我们先来复习一下,假如我们想要ChatGPT来扮演一个[私人营养师]为我们给出 ...
- C# WinForm 中让panel 可以在WinForm 中移动
panelContent.MouseDown += Panel_MouseDown; // 为Panel添加鼠标移动事件处理程序 panelContent.MouseMove += Panel_Mou ...
- docusaurus默认访问地址前缀 以及多实例
前言 默认情况下 所有的md文档 都应该以docs为根目录. you-project |--docs |--test.md 而访问路由 也是默认的http://localhost:3000/docs/ ...