洛谷 P3372:线段树 1 ← 分块算法模板(区间更新、区间查询)

【题目来源】
https://www.luogu.com.cn/problem/P3372

【题目描述】
如题,已知一个数列,你需要进行下面两种操作:
(1)将某区间每一个数加上 k。
(2)求出某区间每一个数的和。

【输入格式】
第一行包含两个整数 n,m,分别表示该数列数字的个数和操作的总个数。
第二行包含 n 个用空格分隔的整数,其中第 i 个数字表示数列第 i 项的初始值。
接下来 m 行每行包含 3 或 4 个整数,表示一个操作,具体如下:
1 x y k:将区间 [x,y] 内每个数加上 k。
2 x y:输出区间 [x,y] 内每个数的和。

【输出格式】
输出包含若干行整数,即为所有操作 2 的结果。

【输入样例】
5 5
1 5 4 2 3
2 2 4
1 2 3 2
2 3 4
1 1 5 1
2 1 4​​​​​​​

【输出样例】
11
8
20

【说明/提示】
对于 30% 的数据:n≤8,m≤10。
对于 70% 的数据:n≤10^3,m≤10^4。
对于 100% 的数据:1≤n,m≤10^5。
保证任意时刻数列中所有元素的绝对值之和 ≤10^18。

【算法分析】
● 本题其实就是
线段树的模板题,这里用来练习分块
● 分块是用线段树的分区思想改良的暴力法。代码比线段树简单。效率比普通暴力法高。分块适合求解 m=n=
10^5 规模的问题。或 m*sqrt(n)≈10^7 的问题。其中,n 为元素个数,m 为操作次数。
● 分块操作的基本要素
(1)块的大小用 block 表示。通常,令
block=sqrt(n)。其中,n 为元素个数。
(2)块的数量用 cnt 表示。其计算公式为
cnt=(n+block-1)/block。或者,用如下更易理解的代码计算 cnt 的值。即:

int block=sqrt(n);
int cnt=n/block;
if(n % block) cnt++;

(3)块的左边界 le[] 及右边界 ri[]。
用 le[i] 和 ri[i] 分别表示块 i 的第一个和最后一个元素的位置。则有:
le[1]=1, ri[1]=block;
le[2]=block+1, ri[2]=2*block;
……
le[i]=(i-1)*block+1, ri[i]=i*block;
……

(4)定义 pos[i] 为第 i 个元素所在的块:pos[i]=(i-1)/block+1。其中,block=sqrt(n)。
(5)定义 sum[i] 为第 i 块的区间和。

for(int i=1; i<=n; i++) sum[pos[i]]+=a[i];

(6)定义 add[i] 为第 i 块的增量,初始值为 0。
一般情况下,区间 [L,R] 跨越了多个块。
在被 [L,R] 完全包含的整块内,更新
add[i]=add[i]+d;
位于整块两头,不能被 [L,R] 完全包含的两个碎块,分别更新
sum(p)=sum(p)+(ri[p]-L+1)*dsum(q)=sum(q)+(R-le[q]+1)*d


【算法代码】

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
const int maxn=1e5+5;

LL a[maxn];
LL le[maxn],ri[maxn],pos[maxn];
LL sum[maxn],add[maxn];
int cnt;

void build(int n) {
    int block=sqrt(n);
    int cnt=n/block;
    if(n%block) cnt++;
    for(int i=1; i<=cnt; i++) {
        le[i]=(i-1)*block+1;
        ri[i]=i*block;
    }
    ri[cnt]=n;

    for(int i=1; i<=n; i++) pos[i]=(i-1)/block+1;
    for(int i=1; i<=n; i++) sum[pos[i]]+=a[i];
}

void update(int L,int R,int d) { //section update
    int p=pos[L],q=pos[R];
    if(p==q) {
        for(int i=L; i<=R; i++) a[i]+=d;
        sum[p]+=(R-L+1)*d;
    } else {
        for(int i=p+1; i<=q-1; i++) add[i]+=d;

        for(int i=L; i<=ri[p]; i++) a[i]+=d;
        sum[p]+=(ri[p]-L+1)*d;

        for(int i=le[q]; i<=R; i++) a[i]+=d;
        sum[q]+=(R-le[q]+1)*d;
    }
}

LL query(int L,int R) { //LL
    int p=pos[L],q=pos[R];
    LL ans=0; //LL
    if(p==q) {
        for(int i=L; i<=R; i++) ans+=a[i];
        ans+=add[p]*(R-L+1);
    } else {
        for(int i=p+1; i<=q-1; i++) ans+=sum[i]+add[i]*(ri[i]-le[i]+1);

        for(int i=L; i<=ri[p]; i++) ans+=a[i];
        ans+=add[p]*(ri[p]-L+1);

        for(int i=le[q]; i<=R; i++) ans+=a[i];
        ans+=add[q]*(R-le[q]+1);
    }
    return ans;
}

int main() {
    int n,m;
    cin>>n>>m;
    for(int i=1; i<=n; i++) cin>>a[i];
    build(n);
    while(m--) {
        int op,a,b,c;
        cin>>op>>a>>b;
        if(op==1) {
            cin>>c;
            update(a,b,c);
        } else cout<<query(a,b)<<endl;
    }

    return 0;
}

/*
in:
5 5
1 5 4 2 3
2 2 4
1 2 3 2
2 3 4
1 1 5 1
2 1 4

out:
11
8
20
*/




【参考文献】
https://blog.csdn.net/m0_52398496/article/details/123233908
https://blog.csdn.net/weixin_45539557/article/details/116461380
https://blog.csdn.net/wzh1378008099/article/details/89243459




 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/627535.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

百面算法工程师 | YOLOv6面试考点原理全解析

本文给大家带来的百面算法工程师是深度学习目标检测YOLOv6面试总结&#xff0c;文章内总结了常见的提问问题&#xff0c;旨在为广大学子模拟出更贴合实际的面试问答场景。在这篇文章中&#xff0c;我们还将介绍一些常见的深度学习目标检测面试问题&#xff0c;并提供参考的回答…

pikachu靶场通关之暴力破解

目录 基于表单的暴力破解 1.打开网站&#xff0c;随便输入一个账号密码&#xff0c;点击登录 2.输入正确的账号密码&#xff0c;点击右上角的提示 3.随便输入账号密码&#xff0c;抓包 4.右键发送到intruder,点击intruder 5.设置攻击位置 6.设置攻击模式&#xff0c;选择…

【十大排序算法】----C语言版插入排序(详细图解)

目录 一&#xff1a;插入排序——原理 二&#xff1a;插入排序——分析 三&#xff1a;插入排序——实现 四&#xff1a;插入排序——效率 一&#xff1a;插入排序——原理 插入排序的原理和基本思想&#xff1a;把待排序的记录按其关键码值的大小逐个插入到一个已经排好序…

Python-VBA函数之旅-zip函数

目录 一、zip函数的常见应用场景 二、zip函数使用注意事项 三、如何用好zip函数&#xff1f; 1、zip函数&#xff1a; 1-1、Python&#xff1a; 1-2、VBA&#xff1a; 2、推荐阅读&#xff1a; 个人主页&#xff1a;https://myelsa1024.blog.csdn.net/ 一、zip函数的常见…

【C语言每日题解】三题:回文检查、刘备 关羽 张飞三人过年放鞭炮、约瑟夫环问题(犹太人死亡游戏)(难度up,推荐)

&#x1f970;欢迎关注 轻松拿捏C语言系列&#xff0c;来和 小哇 一起进步&#xff01;✊ &#x1f308;感谢大家的阅读、点赞、收藏和关注 &#x1f970;希望大家喜欢我本次的讲解 &#x1f31f;非常推荐最后一道题 &#x1f339; 犹太人死亡游戏&#xff0c;建议观看 &…

Milvus的系统架构

简介 Milvus的构建在许多知名的向量搜索库比如Faiss, HNSW, DiskANN, SCANN等之上的&#xff0c;它针对稠密向量数据集的相似搜索而设计&#xff0c;能支持百万、十亿甚至万亿级别的向量搜索。 Milvus支持数据分片&#xff0c;流式数据插入&#xff0c;动态schema&#xff0c…

【数据结构】队列的实现(链式)

文章目录 队列1.队列的概念及结构概念结构 2.队列的实现&#xff08;链式结构&#xff09;队列定义初始化队列入队出队获取队头元素获取队尾元素销毁队列判断队列是否为空队列有效个数 完整代码&#xff08;包含测试代码&#xff09;Queue.hQueue.ctest.c 队列 1.队列的概念及…

PCIE/PCI设备配置空间

PCI/PCIE Capability PCI/PCIE设备的配置空间记录了PCIE设备的capability支持信息&#xff0c;每个capability定义了一个ID标识&#xff0c;可以通过函数pci_find_capability和pci_find_ext_capability来探测和获取这些配置信息的位置。这些ID定义在文件include/uapi/linux/pc…

vue2+Ts中openLayer绘图工具组件封装

vue2Ts中openLayer绘图工具组件封装 效果&#xff1a; 封装组件代码&#xff1a; <!-- openLayer绘图工具 --> <template><a-button-group v-show"isShow"><a-button v-if"shouldShowButton(point)" click"draw(Point)"…

linux的 /usr/sbin/nologin /sbin/nologin /bin/false /etc/nologin 的作用与区别

/usr/sbin/nologin /sbin/nologin /bin/false /etc/nologin 的作用与区别 /usr/sbin/nologin /sbin/nologin /bin/false 这三者的作用几乎一样&#xff0c;都是禁止用户登录。 /usr/sbin/nologin /sbin/nologin 是同一个文件&#xff0c;通过软连接指向。 当把用户的bash设置…

Malbers Inventory System

Inventory插件为Malbers动物管理员生态系统带来了强大的库存系统&#xff0c;具有以下功能&#xff1a;通知系统、库存集、自定义物品反应等 ✔️特征 项目管理 收集和存储项目 库存显示 通知系统 物品所有者 库存集合 项目操作 保存和加载&#xff08;基于JSON.Net&#xff0c…

在 CSS 中使用 text-emphasis 来增强文本的趣味性

在CSS中设置文本样式的方法有很多。您可以更改颜色、大小、字体&#xff0c;甚至添加阴影和轮廓等效果。但最近&#xff0c;我了解到一个我以前没有听说过的时尚 CSS 属性&#xff0c;它非常棒&#xff01; 它被称为文本强调&#xff08;text-emphasis&#xff09;&#xff0c…

python数据可视化:层次聚类热图clustermap()

【小白从小学Python、C、Java】 【考研初试复试毕业设计】 【Python基础AI数据分析】 python数据可视化&#xff1a; 层次聚类热图 clustermap() [太阳]选择题 请问关于以下代码表述错误的选项是&#xff1f; import seaborn as sns import matplotlib.pyplot as plt import n…

低成本窗帘电机解决方案KP81101 3.6A有刷直流电机H桥驱动器代替DRV8871

KP81101是一款有刷直流电机驱动器&#xff0c;适用于家用电器、工业设备和其他有刷直流电机、步进电机应用场合。驱动器由四个 NMOS 构成的 H 桥组成&#xff0c;两个逻辑输入控制全桥驱动器&#xff0c;以驱动直流有刷电机电流双向流动。驱动器的最大峰值电流能力为 3.6A。芯片…

Warning logs 2024-05-15

mysql数据库中文模糊查询时出现异常 Error querying database. Cause: java.sql.SQLException: Illegal mix of collations for operation like Select("select f.* from fundDetails f" " where (case when #{keyword} is not null then f.operateTime like c…

软件项目验收第三方测试报告如何获取

软件项目验收第三方测试报告是确保软件质量、安全性和稳定性的重要环节。对于企业和开发者来说&#xff0c;获取一份全面、专业的第三方测试报告&#xff0c;对于提升软件产品的竞争力和用户满意度至关重要。本文将介绍如何获取软件项目验收第三方测试报告&#xff0c;以及相关…

13.监控redis

1.状态信息 redis-cli keys * info select 0-15#16个库&#xff0c;依次查看即可2.导入模板 在zabbix-server界面-模板-导入-选择文件-redis.xml <?xml version"1.0" encoding"UTF-8"?> <zabbix_export><version>2.0</version&g…

全栈中VUE的install报错说taobao仓库不好使的解决办法

长话短说&#xff0c;就是报错了&#xff0c;直接上干货。 step1&#xff1a;查看设置&#xff0c;主要是看registry npm config getstep2&#xff1a;设置仓库 npm config set registry https://registry.npmmirror.comstep3&#xff1a;再运行步骤一的指令查看仓库是不是变…

Java 循环结构 - for, while 及 do...while

Java 循环结构 - for, while 及 do…while 顺序结构的程序语句只能被执行一次。 如果您想要同样的操作执行多次&#xff0c;就需要使用循环结构。 Java中有三种主要的循环结构&#xff1a; while 循环 do…while 循环 for 循环 在 Java5 中引入了一种主要用于数组的增强型 f…

刷代码随想录有感(66):回溯算法——组合问题的优化(剪枝)

代码&#xff1a;将for循环中i的搜索范围进行缩小&#xff0c;免去多余的不可能符合条件的操作。 for(int i start; i < n-(k-tmp.size())1;i) 实质是剪枝&#xff0c;拿n4,k4作比较&#xff1a; 显然结果只可能是[1,2,3,4]&#xff0c;选取顺序只可能是1-2-3-4&#xff…