【分块】LibreOJ 6280 数列分块入门4
题目
题解
将 \(n\) 个元素的数组 \(a\) 按块长 \(\sqrt{n}\) 进行分块处理。为每个块设置两个懒添加标记 \(add[i], sum[i]\),分别代表这个区间每个元素共同添加的数值大小,区间和(不包括懒添加的值)。
对于区间加操作,将添加值存储在符合整块都进行加法操作的块的懒标记 \(add[i]\) 上,单次操作时间复杂度 \(O(1)\),此类块至多只有 \(\sqrt{n}\) 块,最差时间复杂度 \(O(\sqrt{n})\);未符合整块的进行加法操作则进行暴力处理,即为下标位于 \([l, r]\) 的元素直接添加上 \(c\),单次操作时间复杂度 \(O(\sqrt{n})\),此类块至多只有 \(2\) 块,最差时间复杂度 \(O(2\sqrt{n})\)。
对于区间和操作,将覆盖到的整块的 \(sum[i]\) 直接添加到结果中,并且添加当前块大小乘以 \(add[i]\) 到结果中。单次操作时间复杂度 \(O(1)\),此类块至多只有 \(\sqrt{n}\) 块,最差时间复杂度 \(O(\sqrt{n})\);未符合整块的进行区间和操作则进行暴力处理,单次操作时间复杂度 \(O(\sqrt{n})\),此类块至多只有 \(2\) 块,最差时间复杂度 \(O(2\sqrt{n})\)。
参考代码
#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
using namespace std;
typedef long long ll;
constexpr int N = 50007;
int n, op, l, r, c;
int len;//块长
ll a[N];//数列
ll add[230];//懒添加标记
ll sum[230];//块和
/*初始化块*/
void initPieces() {
len = sqrt(n);
for (int i = 1, j = 1; i <= n; ++ i) {
sum[j] += a[i];
if (i % len == 0) ++ j;
}
}
/*获取下标 x 所在的块的索引*/
int getPieceId(int x) {
return (x - 1) / len + 1;
}
/*获取第 pid 块的大小,即这个块的元素个数*/
int getPieceSize(int pid) {
return min(n, pid * len) - (pid - 1) * len;
}
/*判断下标 x 是否为块的左边界*/
bool isLeftBoundary(int x) {
return (x - 1) % len == 0;
}
/*判断下标 x 是否为块的右边界*/
bool isRightBoundary(int x) {
return x % len == 0;
}
int main() {
IOS
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;
bool isLe = isLeftBoundary(l), isRi = isRightBoundary(r);
int le = getPieceId(l), ri = getPieceId(r);
if (op) {//区间和
++ c;
ll res = 0LL;
for (int i = isLe ? le : le + 1, j = isRi ? ri : ri - 1; i <= j; ++ i) {
res = (res + sum[i] % c + add[i] * getPieceSize(i) % c) % c;
}
if (!isLe) {
while (l <= r) {
res = (res + add[le] + a[l]) % c;
if (isRightBoundary(l)) break;
++ l;
}
}
if (!isRi) {
while (l <= r) {
res = (res + add[ri] + a[r]) % c;
if (isLeftBoundary(r)) break;
-- r;
}
}
cout << res << '\n';
} else {//区间加
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;
sum[le] += c;
if (isRightBoundary(l)) break;
++ l;
}
}
if (!isRi) {
while (l <= r) {
a[r] += c;
sum[ri] += c;
if (isLeftBoundary(r)) break;
-- r;
}
}
}
}
return 0;
}
【分块】LibreOJ 6280 数列分块入门4的更多相关文章
- LibreOJ 6280 数列分块入门 4(分块区间加区间求和)
题解:分块的区间求和比起线段树来说实在是太好写了(当然,复杂度也高)但这也是没办法的事情嘛.总之50000的数据跑了75ms左右还是挺优越的. 比起单点询问来说,区间询问和也没有复杂多少,多开一个su ...
- LibreOJ 6280 . 数列分块入门 4
题目链接:https://loj.ac/problem/6280 加一个数组保存块的和. 代码: #include<iostream> #include<cstring> #i ...
- LOJ #6280. 数列分块入门 4-分块(区间加法、区间求和)
#6280. 数列分块入门 4 内存限制:256 MiB时间限制:500 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: hzwer 提交提交记录统计测试数据讨论 题目描述 给出一个 ...
- LibreOJ 6277. 数列分块入门 1 题解
题目链接:https://loj.ac/problem/6277 题目描述 给出一个长为 \(n\) 的数列,以及 \(n\) 个操作,操作涉及区间加法,单点查值. 输入格式 第一行输入一个数字 \( ...
- LibreOJ 6277 数列分块入门 1(分块)
题解:感谢hzwer学长和loj让本蒟蒻能够找到如此合适的入门题做. 这是一道非常标准的分块模板题,本来用打标记的线段树不知道要写多少行,但是分块只有这么几行,极其高妙. 代码如下: #include ...
- LibreOJ 6278. 数列分块入门 2 题解
题目链接:https://loj.ac/problem/6278 题目描述 给出一个长为 \(n\) 的数列,以及 \(n\) 个操作,操作涉及区间加法,询问区间内小于某个值 \(x\) 的元素个数. ...
- LibreOJ 6285. 数列分块入门 9
题目链接:https://loj.ac/problem/6285 其实一看到是离线,我就想用莫队算法来做,对所有询问进行分块,但是左右边界移动的时候,不会同时更新数字最多的数,只是后面线性的扫了一遍, ...
- LibreOJ 6282. 数列分块入门 6
题目链接:https://loj.ac/problem/6282 参考博客:http://www.cnblogs.com/stxy-ferryman/p/8560551.html 这里如果用数组的话元 ...
- LibreOJ 6277. 数列分块入门 2
题目链接:https://loj.ac/problem/6278 参考博客:https://blog.csdn.net/qq_36038511/article/details/79725027 这题我 ...
- LibreOJ 6277. 数列分块入门 1
题目链接:https://loj.ac/problem/6277 参考博客:https://www.cnblogs.com/stxy-ferryman/p/8547731.html 两个操作,区间增加 ...
随机推荐
- Hugging Face NLP课程学习记录 - 2. 使用 Hugging Face Transformers
Hugging Face NLP课程学习记录 - 2. 使用 Hugging Face Transformers 说明: 首次发表日期:2024-09-19 官网: https://huggingfa ...
- Git常用命令,分支合并与管理
Git 自我感觉最大的优点是对版本库和分支的管理 各自的电脑都对项目保存一份版本,分支合并也极其方便. 而且Git的目录操作命令跟Linux一样,使用起来还是非常顺手的. Git详解 Git 常用命令 ...
- Android Qcom USB Driver学习(五)
前面的几篇都有涉及,所以本文学习一下pmic usb charger都相关的vote机制 OVP: Over Voltage Protection 过压保护 USB_IN: Input current ...
- aarch64 和 ARMV8 的区别
aarch64 和 ARMv8 是紧密相关但涵义不同的术语,在解释他们的区别之前,让我们先简单理解它们各自的含义: ARMv8: ARMv8 是指 ARM 架构的第八个版本,这是由 ARM Holdi ...
- CSharp的@microsoft/signalr实时通信教程 - 前端 vue
1. 安装@microsoft/signalr pnpm install @microsoft/signalr --save signalr 是微软对 websocket技术的封装,优化了操作 :1. ...
- AJE润色优惠,35%的优惠券
AJE润色 折扣35%的优惠,如下所示 全网目前只有如下优惠 USTCJC扣10% DOCTOR22扣15%,AJENEW22扣260 10%的可以和15%的叠加成-25% 10的也可以和260叠加成 ...
- 工作使用:Exchange问题汇总
工作使用:Exchange问题汇总 1:邮件不能发给公司内部的人,但是可以发公司外部人员 解析:GC出问题 2:xchange 2016环境,最近经常发生邮件队列堆积的现象.邮件服务器整体性能看上去没 ...
- 如何在Windows 11系统中将任意文件(如bat/log等)固定在开始菜单?
在Windows 11系统中,默认只支持将.exe/文件夹/.zip固定在开始菜单,如果想将其他文件如.bat/.log等文件固定在开始菜单将在右键菜单中找不到选项. 一个更简单的办法: 对任意文件右 ...
- jmeter测试rpc接口-使用dubbo框架调用
1.下载用于测试dubbo的spring boot项目 参考文章: http://t.zoukankan.com/111testing-p-11297038.html https://zhuanlan ...
- AI辅助动画制作,现实到虚拟仅需要一个摄像头。多种AI技术融合赋能传统行业,或是产业趋势?
图源:youtube authour autodesk media & entertainment 不是元宇宙,是动画. 2024年10.30日.美国加利福尼亚公司 Wonder dynami ...