前言

分块是一种优雅的暴力,将数组按块长 \(\sqrt{n}\) 进行分块,可实现区间加法、区间求和和区间逆序对计数等场景,进行 \(m\) 次操作的时间复杂度:\(O(m\sqrt{n})\)。

对于整个块都进行操作,可以用打上标记的方式来取代操作这个块的全部元素,由于最多只需要处理 \(\sqrt{n}\) 个块,因此这个操作的时间复杂度是 \(O(\sqrt{n})\)。对于不属于整个块的部分,直接进行暴力处理,易知这样子的块最多只有两个,需要处理的元素至多只有 \(2 * \sqrt{n} - 2\) 个,因此这步操作时间复杂度也是 \(O(\sqrt{n})\)。

题目

https://loj.ac/p/6277

题解

将 \(n\) 个元素的数组 \(a\) 按块长 \(\sqrt{n}\) 进行分块处理。为每个块设置一个懒添加标记 \(add[i]\),代表这个区间每个元素共同添加的数值大小。

对于 \(opt = 0\) 的情况:将添加值存储在符合整块都进行加法操作的块的懒标记 \(add[i]\) 上,未符合整块都进行加法操作则进行暴力处理。

对于 \(opt = 1\) 的情况:直接输出 \(a[r] + add[getPieceId(r)]\)。

参考代码

#include<bits/stdc++.h>
using namespace std;
using ll = long long; int n;//数列元素个数
int op, l, r, c;
int len;//块长
ll a[50005];//数列
ll add[230];//每个块的懒添加标记 /*初始化块*/
void initPieces() {
len = sqrt(n);
} /*获取下标 x 所在的块的索引*/
int getPieceId(int x) {
return (x - 1) / len + 1;
} /*判断下标 x 是否为块的左边界*/
bool isLeftBoundary(int x) {
return (x - 1) % len == 0;
} /*判断下标 x 是否为块的右边界*/
bool isRightBoundary(int x) {
return x % len == 0;
} int main() {
ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
cin >> n;
for (int i = 1; i <= n; ++ i) cin >> a[i];
initPieces();
for (int i = 0; i < n; ++ i) {
cin >> op >> l >> r >> c;
if (op) {
cout << a[r] + add[getPieceId(r)] << '\n';
} else {
bool isLe = isLeftBoundary(l), isRi = isRightBoundary(r);
int le = getPieceId(l), ri = getPieceId(r);
//首先处理整块的内容
for (int i = isLe ? le : le + 1, j = isRi ? ri : ri - 1; i <= j; ++ i) add[i] += c;
//其次处理左边不满一块的内容
if (!isLe) {
while (l <= r) {
a[l] += c;
if (isRightBoundary(l)) break;
++ l;
}
}
//最后处理右边不满一块的内容
if (!isRi) {
while (l <= r) {
a[r] += c;
if (isLeftBoundary(r)) break;
-- r;
}
}
}
}
return 0;
}

【分块】LibreOJ 6277 数列分块入门1的更多相关文章

  1. LibreOJ 6277. 数列分块入门 1 题解

    题目链接:https://loj.ac/problem/6277 题目描述 给出一个长为 \(n\) 的数列,以及 \(n\) 个操作,操作涉及区间加法,单点查值. 输入格式 第一行输入一个数字 \( ...

  2. LibreOJ 6277. 数列分块入门 1

    题目链接:https://loj.ac/problem/6277 参考博客:https://www.cnblogs.com/stxy-ferryman/p/8547731.html 两个操作,区间增加 ...

  3. LibreOJ 6277 数列分块入门 1(分块)

    题解:感谢hzwer学长和loj让本蒟蒻能够找到如此合适的入门题做. 这是一道非常标准的分块模板题,本来用打标记的线段树不知道要写多少行,但是分块只有这么几行,极其高妙. 代码如下: #include ...

  4. LibreOJ 6277. 数列分块入门 2

    题目链接:https://loj.ac/problem/6278 参考博客:https://blog.csdn.net/qq_36038511/article/details/79725027 这题我 ...

  5. LOJ #6277. 数列分块入门 1-分块(区间加法、单点查询)

    #6277. 数列分块入门 1 内存限制:256 MiB时间限制:100 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: hzwer 提交提交记录统计测试数据讨论 2   题目描述 给出 ...

  6. LOJ——#6277. 数列分块入门 1

    ~~推荐播客~~ 「分块」数列分块入门1 – 9 by hzwer 浅谈基础根号算法——分块 博主蒟蒻,有缘人可直接观摩以上大佬的博客... #6277. 数列分块入门 1 题目大意: 给出一个长为 ...

  7. LibreOJ 6278. 数列分块入门 2 题解

    题目链接:https://loj.ac/problem/6278 题目描述 给出一个长为 \(n\) 的数列,以及 \(n\) 个操作,操作涉及区间加法,询问区间内小于某个值 \(x\) 的元素个数. ...

  8. LOJ#6277. 数列分块入门 1

    分块思想,先把原来的序列分成根号n快,然后对于更新的部分,先操作这个序列边上的部分,然后再中间部分整块操作,这样复杂度就是O(根号N) #include<map> #include< ...

  9. LibreOJ 6285. 数列分块入门 9

    题目链接:https://loj.ac/problem/6285 其实一看到是离线,我就想用莫队算法来做,对所有询问进行分块,但是左右边界移动的时候,不会同时更新数字最多的数,只是后面线性的扫了一遍, ...

  10. LibreOJ 6282. 数列分块入门 6

    题目链接:https://loj.ac/problem/6282 参考博客:http://www.cnblogs.com/stxy-ferryman/p/8560551.html 这里如果用数组的话元 ...

随机推荐

  1. mysql 批量有则修改,无则新增

    需要为表添加唯一索引 alter table tb_*** add unique index(aa,bb); -- 此条为联合唯一索引INSERT INTO<include refid=&quo ...

  2. 【赵渝强老师】Kafka的持久化

    一.Kafka持久化概述 Kakfa 依赖文件系统来存储和缓存消息.对于硬盘的传统观念是硬盘总是很慢,基于文件系统的架构能否提供优异的性能?实际上硬盘的快慢完全取决于使用方式.同时 Kafka 基于 ...

  3. 单Master节点的k8s集群部署-完整版

    K8S 安装步骤 一.准备工作 1.准备三台主机(一台Master节点,两台Node节点)如下: 角色 IP 内存 核心 磁盘 Master 192.168.116.131 4G 4个 55G Nod ...

  4. 开源的键鼠共享工具「GitHub 热点速览」

    十一长假回来,我的手放在落灰的键盘上都有些陌生了,红轴竟敲出了青轴般的响声,仿佛在诉说对假期结束的不甘. 假期回归的首更,让我们看看又有什么好玩的开源项目冲上了开源热榜.一套键盘和鼠标控制多台电脑的工 ...

  5. 数据库日常实操优质文章分享(含Oracle、MySQL等) | 2023年2月刊

    本文为大家整理了墨天轮数据社区2023年2月发布的优质技术文章,主题涵盖Oracle.MySQL.PostgreSQL等数据库的环境搭建.故障处理等日常实践操作,以及概念梳理.常用脚本等总结记录,分享 ...

  6. C++第五节课 函数默认值 函数重载

    #include <iostream> using namespace std; // C++的函数默认值和函数重载 // 函数参数的入栈规则从右往左开始入栈 // 函数重载机制(第一种静 ...

  7. DOM 操作的常用 API 有哪些 ?

    DOM 操作的常用 API 就是DOM 通过API (接口)获取页面(html)元素: 1. 节点查询 API 1.1 document.querySelector()  选择第一个匹配的元素 1.2 ...

  8. 两小时学会使用dubbo(直接API、spring、注解、springboot)

    最近上新的项目中需要用到dubbo,于是我决定温故知新,决定分享一下Dubbo在各种环境下的使用方式,本篇文章让你两小时就能学会使用dubbo 什么是Dubbo Dubbo是一个分布式.高性能.透明化 ...

  9. 在 K8s 集群上部署 RabbitMQ 实战

    作者:老Z,云原生爱好者,目前专注于云原生运维,KubeSphere Ambassador. 前言 知识点 定级:入门级 RabbitMQ 单节点安装部署 RabbitMQ 集群安装部署 GitOps ...

  10. 常见APR攻击及其防护

    0x01 什么是ARP 地址解析协议--ARP:是根据IP地址获取物理地址的一个TCP/IP协议.主机发送信息时将包含目标IP地址的ARP请求广播到局域网络上的所有主机,并接收返回消息,以此确定目标的 ...