题解【loj6277】数列分块入门1
题目描述
给出一个长为\(n\)的数列,以及\(n\)个操作,操作涉及区间加法,单点查值。
输入格式
第一行输入一个数字\(n\)。
第二行输入\(n\)个数字,第\(i\)个数字为\(a_{i}\),以空格隔开。
接下来输入\(n\)行询问,每行输入四个数字\(opt\)、\(l\)、\(r\)、\(c\),以空格隔开。
若\(opt = 0\),表示将位于\([l, r]\)的之间的数字都加\(c\)。
若\(opt = 1\),表示询问\(a_{r}\)的值(\(l\)和\(c\)忽略)。
输出格式
对于每次询问,输出一行一个数字表示答案。
样例
样例输入
4
1 2 2 3
0 1 3 1
1 0 1 0
0 1 2 2
1 0 2 0
样例输出
2
5
数据范围与提示
对于所有的数据,\(1 \leq n \le 50000\) ,\(-2^{31} \leq others、ans \le 2_{31} - 1\) 。
题解
这是一道很好的分块入门题。
所谓分块,就是一种通过将一个序列分成多块后,在每块上打标记以实现快速区间修改,区间查询的一种算法。其均摊时间复杂度为\(\Theta\sqrt{n}\)。
在一般情况下,每个块的长度都为\(\sqrt{n}\)。
分块,被尊称为优雅的暴力,因此它的代码难度也不算高。总之,比线段树、树状数组等毒瘤数据结构的代码难度低。
我们需要建立三个数组:
- \(a[]\),为题目中输入的序列;
- \(b[]\),记录每个序列中的每个数在那一块;
- \(add[]\),为序列的标记数组。
话不多说,上代码。
代码
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <cctype>//头文件准备
using namespace std;//使用标准名字空间
inline int gi()//快速读入
{
int f = 1, x = 0; char c = getchar();
while (c < '0' || c > '9') { if (c == '-')f = -1; c = getchar();}
while (c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar();}
return f * x;
}
int a[50005], b[50005], add[50005], len, n, m;//a[],b[],add[]的意思如分析,len为每一块的长度,n为序列长度,m为询问个数,在本题中=n。
inline void modify(int l, int r, int x)//区间修改的自定义函数
{
for (int i = l; i <= min(r, b[l] * len); i++) a[i] = a[i] + x;//增加序列中的数
if (b[l] != b[r])//如果要修改的不在同一个块中
{
for (int i = (b[r] - 1) * len + 1; i <= r; i++) a[i] = a[i] + x;//继续增加序列中的数
}
for (int i = b[l] + 1; i <= b[r] - 1; i++) add[i] = add[i] + x;//给区间内的数增加标记
}
int main()//进入主函数
{
n = gi();//输入元素个数
len = sqrt(n);//求出每个块的长度
for (int i = 1; i <= n; i++) a[i] = gi();//输入序列中的数
for (int i = 1; i <= n; i++) b[i] = (i - 1) / len + 1;//求出序列中的数分别属于哪一个块
for (int p = 1; p <= n; p++)
{
int fl = gi(), l = gi(), r = gi(), w = gi();//输入操作的描述
if (!fl)//如果是修改
{
modify(l, r, w);//修改区间内的数
}
else//否则就是求出某个数
{
printf("%d\n", a[r] + add[b[r]]);//输出这个位置的数的标记和它在序列中原本的数的和
}
}
return 0;//完美结束
}
题解【loj6277】数列分块入门1的更多相关文章
- 题解——loj6277 数列分块入门1(分块)
分块裸题 然后就是记得左右边界处理和分块的初始化 忘了初始化会被卡成暴力 #include <cstdio> #include <algorithm> #include < ...
- 题解——loj6281 数列分块入门5 (分块)
分块 若块内最大值为0或1,则不用再开方 然后暴力修改 可以证明,如果开方后向下取整,则最多开方4次一个数就会变成0或1 #include <cstdio> #include <cm ...
- 题解——loj6280 数列分块入门4 (分块)
分块维护一个区间和 然后记得更新的时候左边角块的tag不要打错到右边角块 #include <cstdio> #include <algorithm> #include < ...
- [LOJ6277]数列分块入门 1
题目大意: 给你一个长度为$n(n\leq 50000)$的序列$A$,支持进行以下两种操作: 1.将区间$[l,r]$中所有数加上$c$: 2.询问$A_r$的值.思路: 分块. 对于整块的数据打标 ...
- loj6277 数列分块入门题1
裸题分块. #include <bits/stdc++.h> using namespace std; ],b[],n,m,t1,t2,t3,t4,sq; int main(){ ios: ...
- 题解——loj6279 数列分块入门3 (分块)
用set维护有序序列 或许sort也可以,但这题的前驱定义是严格小于 所以要去重 然后就是记得自己打的加法tag在query的时候一定要算上 话说这题数据有点fake啊忘了查询算上自己的标记了还有70 ...
- 题解——loj6278 数列分块入门2 (分块)
查询小于k的值 注意lower_bound一定要减去查找的起始位置得到正确的位置 调了快两天 淦 #include <cstdio> #include <algorithm> ...
- LOJ6277~6285 数列分块入门
Portals 分块需注意的问题 数组大小应为,因为最后一个块可能会超出的范围. 当操作的区间在一个块内时,要特判成暴力修改. 要清楚什么时候应该+tag[t] 数列分块入门 1 给出一个长为的数列, ...
- 数列分块入门九题(一):LOJ6277~6279
Preface 分块,一个神奇的暴力算法.可以把很多\(O(n^2)\)的数据结构题的暴力优化到常数极小的\(O(n\sqrt n)\).当一些毒瘤题无法用线段树,主席树,平衡树,树状数组...... ...
- LibreOJ6279. 数列分块入门 3 题解
题目链接:https://loj.ac/problem/6279 题目描述 给出一个长为 \(n\) 的数列,以及 \(n\) 个操作,操作涉及区间加法,询问区间内小于某个值 \(x\) 的前驱(比其 ...
随机推荐
- luoguP5219 无聊的水题 I 多项式快速幂
有一个幼儿园容斥:最大次数恰好为 $m=$ 最大次数最多为 $m$ - 最大次数最多为 $m-1$. 然后来一个多项式快速幂就好了. code: #include <cmath> #in ...
- CF895C Square Subsets [线性基]
线性基的题- 考虑平方数只和拆解质因子的个数的奇偶性有关系 比如说你 \(4\) 和 \(16\) 的贡献都是一样的.因为 \(4 = 2^2 , 16 = 2^4\) \(2\) 和 \(4\) 奇 ...
- Java集合之Arrays 剖析
Arrays工具类位于 java.util 包下,是一个比较常用的工具类,其可以针对数组进行各种操作,比如赋值.排序.搜索等等.在项目过程中我们针对数组的有关操作,如果不方便直接操作,均可通过调用此类 ...
- JavaScript 删除某个数组中指定的对象和删除对象属性
Javascript: 删除指定对象:使用过程中只适合删除对象,如果数组中添加的是类型Function的话是删除不了的. function removeObjWithArr(_arr,_obj) { ...
- 前端开发 css、less编写规范
壹 ❀ 引 早在大半年前,我在负责整理定义了前端组JavaScript开发规范与less.css样式开发规范.一直想将两个规范整理成文章,但在整理了JavaScript规范后,我花了较多的时间在学习J ...
- 2019.2.21 T2题解
meet 大概思路就是 , 找出相交的路径 , 判断方向 , 分类讨论.. 假设已经找出了相交路径 ... 若方向相同 , 则找到相交路径上边权的最大值 , 若最大值>出发时间差 , 则可行. ...
- Python之六:模块
模块包含了大量的函数方法和变量,我们可以用下面的语句调用模块: import 模块名 这样我们就可以在后面的语句中使用模块中的函数或者变量了.调用时只需用 模块名.函数名的方式调用即可 from ...
- phpstudy+phpstorm 浏览器没有解析php文件,直接显示源码
用phpstorm编辑完项目,右键浏览器预览时页面报错:502 Bad Gateway PhpStorm 2019.1 此时默认打开的地址是:localhost:63339/开头的一长串…… 查资料说 ...
- 将字符串转换为double类型的list
var data=“3.039,3.977,3.677,5.855,12.341,6.771”; 方法一: var result=datas.Split(',').ToList().ConvertAl ...
- 占位 RK
占位 RK include: RK403 RK404