线段树区间乘、加,范围求和,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的更多相关文章

  1. AC日记——【模板】线段树 1 洛谷 P3372

    题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.求出某区间每一个数的和 输入输出格式 输入格式: 第一行包含两个整数N.M,分别表示该数列数字的个数和操作的总个 ...

  2. AC日记——【模板】线段树 2 洛谷 P3373

    P3373 [模板]线段树 2387通过1.8K提交标签难度 提高+/省选- 提交 讨论 题解 最新讨论 更多讨论 2333最后三个点卡常数.迷之RE感觉这题很迷啊好像一共三组测试数据.友情提示:开l ...

  3. 【线段树】洛谷 P3372 【模板】线段树 1

    动态开结点线段树板子. #include<cstdio> using namespace std; typedef long long ll; ll sumv[400005],delta[ ...

  4. P3372 【模板】线段树 1 洛谷

    https://www.luogu.org/problem/show?pid=3372 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.求出某区间每一个数的和 ...

  5. 线段树【洛谷P2894】 [USACO08FEB]酒店Hotel

    P2894 [USACO08FEB]酒店Hotel 参考样例,第一行输入n,m ,n代表有n个房间,编号为1---n,开始都为空房,m表示以下有m行操作,以下 每行先输入一个数 i ,表示一种操作: ...

  6. [虚树模板] 洛谷P2495 消耗战

    题意:给定树上k个点,求切断这些点到根路径的最小代价.∑k <= 5e5 解:虚树. 构建虚树大概是这样的:设加入点与栈顶的lca为y,比较y和栈中第二个元素的DFS序大小关系. 代码如下: i ...

  7. 洛谷P3372线段树模板1——线段树

    题目:https://www.luogu.org/problemnew/show/P3372 线段树模板. 代码如下: #include<iostream> #include<cst ...

  8. [AHOI 2009] 维护序列(线段树模板题)

    1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec  Memory Limit: 64 MB Description 老师交给小可可一个维护数列的任务,现在小 ...

  9. hdu1823(二维线段树模板题)

    hdu1823 题意 单点更新,求二维区间最值. 分析 二维线段树模板题. 二维线段树实际上就是树套树,即每个结点都要再建一颗线段树,维护对应的信息. 一般一维线段树是切割某一可变区间直到满足所要查询 ...

  10. [POJ2104] 区间第k大数 [区间第k大数,可持久化线段树模板题]

    可持久化线段树模板题. #include <iostream> #include <algorithm> #include <cstdio> #include &l ...

随机推荐

  1. Linux ls 查看目录结构与文档信息

    摘要:Linux ls命令用于列出目标目录中所有的子目录和文件,发掘并掌握ls命令及其参数设置可以驾轻就熟地管理文件,随心所欲地浏览并确定所在的位置! ls命令介绍   今天,楼兰胡杨继续跟各位猿友一 ...

  2. MySQL Explain查看执行计划详解

    目录 前言 EXPLAIN 中的列 id 和select_type table type possible_keys key 和 key_len ref 和 rows Extra 小结 Referen ...

  3. Matlab使用yalmip与cplex12.10

    本文同步发布于我的网站 软件版本 MATLAB R2023b yalmip 2021-03-31 CPLEX 12.10 不求新,但求适配.此版本组合经过我在两台电脑上成功安装 下载链接 链接:htt ...

  4. HarmonyOS运动开发:精准估算室内运动的距离、速度与步幅

    前言 在室内运动场景中,由于缺乏 GPS 信号,传统的基于卫星定位的运动数据追踪方法无法使用.因此,如何准确估算室内运动的距离.速度和步幅,成为了运动应用开发中的一个重要挑战.本文将结合鸿蒙(Harm ...

  5. HNU FPGA课设项目上手指南

    1.介绍 本文章旨在帮助HNU的同学更优雅的完成数电的FPGA课设(使用DE2-115),文章将涉及完成FPGA项目需要掌握的知识,资源分享以及一些关于完成项目的经验指导.大家快快搬好小板凳,准备发车 ...

  6. 「Note」字符串方向 - 自动机相关

    1. AC 自动机 ACAM 1.1. 简介 AC 自动机用于解决多模式串匹配问题,例如求多个模式串在文本串中的出现次数.显著地,它的应用实际上非常广泛. 借助 KMP 的思想,我们对 Trie 树上 ...

  7. 解密prompt系列55.Agent Memory的工程实现 - Mem0 & LlamaIndex

    记忆存储是构建智能个性化.越用越懂你的Agent的核心挑战.上期我们探讨了模型方案实现长记忆存储,本期将聚焦工程实现层面. What:记忆内容(手动管理 vs 自动识别) How:记忆处理(压缩/抽取 ...

  8. 肝了一个月整理了这份Java学习路线导图

    很多人都在问应该怎么样学习java的知识点,java有哪些知识点?最近准备面试了,java知识点太多了又不知道如何开始复习?java的知识点太多太多,学完了又忘了.所以我们可以为每个知识点都整理成一份 ...

  9. Spring中的一些注解

    @SuppressWarnings("all") 隐藏一些无意义的报错提示 ** @ConfigurationProperties(prefix = "spring.da ...

  10. 如何在FastAPI中巧妙玩转数据脱敏,让敏感信息安全无忧?

    扫描二维码 关注或者微信搜一搜:编程智域 前端至全栈交流与成长 发现1000+提升效率与开发的AI工具和实用程序:https://tools.cmdragon.cn/ 一.Pydantic模型敏感字段 ...